You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2544 lines
75 KiB
2544 lines
75 KiB
|
|
// var fileref = null; |
|
// fileref = document.createElement( 'script' ) |
|
// fileref.setAttribute( "type", "text/javascript" ); |
|
// fileref.setAttribute( "src", "./unit2.js" ); |
|
// document.getElementsByTagName( "head" )[0].appendChild( fileref ); |
|
// fileref = document.createElement( 'script' ); |
|
// fileref.setAttribute( "type", "text/javascript" ); |
|
// fileref.setAttribute( "src", "./unit3.js" ); |
|
// document.getElementsByTagName( "head" )[0].appendChild( fileref ); |
|
//fileref = document.createElement( 'script' ); |
|
//fileref.setAttribute( "type", "text/javascript" ); |
|
//fileref.setAttribute( "src", "./js/audio_worker.js" ); |
|
//document.getElementsByTagName( "head" )[0].appendChild( fileref ); |
|
|
|
|
|
var g_rec = []; |
|
var g_totalAudioData = ""; |
|
|
|
if ( ( !ArrayBuffer.prototype.slice ) || ( ArrayBuffer.prototype.slice == "undifined" ) ) |
|
{ |
|
//Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's |
|
//bytes from `begin`, inclusive, up to `end`, exclusive |
|
ArrayBuffer.prototype.slice = function (begin, end) { |
|
//If `begin` is unspecified, Chrome assumes 0, so we do the same |
|
if (begin === void 0) |
|
{ |
|
begin = 0; |
|
} |
|
|
|
//If `end` is unspecified, the new ArrayBuffer contains all |
|
//bytes from `begin` to the end of this ArrayBuffer. |
|
if (end === void 0) { |
|
end = this.byteLength; |
|
} |
|
|
|
//Chrome converts the values to integers via flooring |
|
begin = Math.floor(begin); |
|
end = Math.floor(end); |
|
|
|
//If either `begin` or `end` is negative, it refers to an |
|
//index from the end of the array, as opposed to from the beginning. |
|
if (begin < 0) { |
|
begin += this.byteLength; |
|
} |
|
if (end < 0) { |
|
end += this.byteLength; |
|
} |
|
|
|
//The range specified by the `begin` and `end` values is clamped to the |
|
//valid index range for the current array. |
|
begin = Math.min(Math.max(0, begin), this.byteLength); |
|
end = Math.min(Math.max(0, end), this.byteLength); |
|
|
|
//If the computed length of the new ArrayBuffer would be negative, it |
|
//is clamped to zero. |
|
if (end - begin <= 0) { |
|
return new ArrayBuffer(0); |
|
} |
|
|
|
var result = new ArrayBuffer(end - begin); |
|
var resultBytes = new Uint8Array(result); |
|
var sourceBytes = new Uint8Array(this, begin, end - begin); |
|
|
|
resultBytes.set(sourceBytes); |
|
|
|
return result; |
|
}; |
|
} |
|
//define |
|
var DATAH264 = 0; |
|
var DATAJPEG = 2; |
|
var DATAH265 = 4; |
|
var DATATYPE_G711U = 5; |
|
var DATATYPE_AAC = 6; |
|
var DATAG711U = 1; |
|
var DATAAAC = 2; |
|
var FRAME_I = 1; |
|
var FRAME_P = 0; |
|
var SES = 0;//Server Send Event |
|
var WS_WR = 1;//Websocket And Worker |
|
var WS = 2;//Websocket |
|
|
|
// |
|
var P_ONE_DEC_ONE_WS = 0; |
|
var P_MLT_DEC_MLT_WS = 1; |
|
var P_MLT_DEC_ONE_WS = 2; |
|
var S_ONE_DEC_ONE_WS = 3;//acturally same as 0 |
|
|
|
function _codec_para() |
|
{ |
|
this.worker_num = 1; |
|
this.vc = [];//video container format is { width: 1920, height: 1088, id: divid, framesize: 512K }; |
|
this.uid = [];//something like this 1483093469437 |
|
this.decode = []; |
|
this.droplatencydecoded = false; |
|
} |
|
|
|
function parseHexString( str ) |
|
{ |
|
var buffer_length = parseInt( ( str.length / 2 ) ); |
|
if ( str.length / 2 ) |
|
buffer_length += 1; |
|
|
|
var result = new Uint8Array( buffer_length ); |
|
var pos = 0; |
|
var converted = 0; |
|
|
|
while( str.length > converted ) |
|
{ |
|
result[ pos ] = parseInt( str.substring( converted, converted + 2 ), 16 ); |
|
pos ++; |
|
converted += 2; |
|
} |
|
|
|
//console.log( "0x " + result[0].toString(16) + result[1].toString(16) + result[2].toString(16) + result[3].toString(16) ); |
|
return result; |
|
} |
|
|
|
function isHeaderPreamble( byte ) |
|
{ |
|
if ( ( byte[ 0 ] == 0x57 )&&( byte[ 1 ] == 0x57 )&&( byte[ 2 ] == 0 )&&( byte[ 3 ] == 0 ) ) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
function getHeaderDataType( byte ) |
|
{ |
|
return byte[22]; |
|
} |
|
|
|
function getHeaderChannel( byte ) |
|
{ |
|
return byte[ 17 ]; |
|
} |
|
|
|
function mywaiting( delay ) |
|
{ |
|
var start = new Date().getTime(); |
|
while (new Date().getTime() < start + delay) |
|
{ |
|
}; |
|
} |
|
|
|
function plusZero( nNum ) |
|
{ |
|
return ( ( nNum < 10 ) ? ( "0" + nNum ) : nNum ); |
|
} |
|
|
|
function getHeaderTimeString( utc_sec ) |
|
{ |
|
var dt = new Date( 0 ); |
|
dt.setUTCSeconds( utc_sec ); |
|
|
|
var retString; |
|
var yyyy = dt.getUTCFullYear(); |
|
var mm = plusZero( dt.getUTCMonth() + 1 ); |
|
var dd = plusZero( dt.getUTCDate() ); |
|
var hh = plusZero( dt.getUTCHours() ); |
|
var mi = plusZero( dt.getUTCMinutes() ); |
|
var ss = plusZero( dt.getUTCSeconds() ); |
|
|
|
var spaceStr = " "; |
|
retString = yyyy + "/" + mm + "/" + dd + spaceStr + hh + ":" + mi + ":" + ss; |
|
return retString; |
|
} |
|
|
|
function getHeaderTime( byte ) |
|
{ |
|
var total_sec = 0; |
|
var utc_sec = ( ( byte[12] << 24 ) | ( byte[ 11 ] << 16 ) | ( byte[ 10 ] << 8 ) | byte[ 9 ] ); |
|
var tz_info = byte[ 23 ]; |
|
var tz_sec = 0; |
|
if ( tz_info > 0 ) |
|
{ |
|
var hr = ( tz_info & 0x78 ) >> 3; |
|
var min = 0; |
|
var mincase = ( tz_info & 0x07 ); |
|
switch ( mincase ) |
|
{ |
|
case 0x03: |
|
min = 45; |
|
break; |
|
case 0x02: |
|
min = 30; |
|
break; |
|
case 0x01: |
|
min = 15; |
|
break; |
|
default: |
|
min = 0; |
|
break; |
|
} |
|
|
|
tz_sec = ( hr * 3600 )+( min * 60 ); |
|
if( tz_info & 0x80 ) |
|
{ |
|
total_sec = ( utc_sec - tz_sec ); |
|
} |
|
else |
|
{ |
|
total_sec = ( utc_sec + tz_sec ); |
|
} |
|
} |
|
else |
|
total_sec = utc_sec; |
|
|
|
return total_sec; |
|
// var dt = new Date( 0 ); |
|
// dt.setUTCSeconds( total_sec ); |
|
// |
|
// var retString; |
|
// var yyyy = dt.getUTCFullYear(); |
|
// var mm = plusZero( dt.getUTCMonth() + 1 ); |
|
// var dd = plusZero( dt.getUTCDate() ); |
|
// var hh = plusZero( dt.getUTCHours() ); |
|
// var mi = plusZero( dt.getUTCMinutes() ); |
|
// var ss = plusZero( dt.getUTCSeconds() ); |
|
// |
|
// var spaceStr = " "; |
|
// retString = yyyy + "/" + mm + "/" + dd + spaceStr + hh + ":" + mi + ":" + ss; |
|
// return retString; |
|
} |
|
|
|
function getHeaderId( byte ) |
|
{ |
|
return byte[17]; |
|
} |
|
//NALU_VPS_NUT = 32, // video parameter set |
|
//NALU_SPS_NUT = 33, // sequence parameter set |
|
function H265_NALU( x ) |
|
{ |
|
return ( ( ( x )& 0x7E ) >> 1 ); |
|
} |
|
function isH26XData( byte , shift )//we could lock the streaming by add our own encrpt in the front. |
|
{ |
|
if (( byte[ shift + 0] == 0 ) && ( byte[ shift + 1] == 0 ) && ( byte[ shift + 2] == 0 ) && ( byte[ shift + 3] == 1 )) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
function isMobBs( )//is mobile browser |
|
{ |
|
if( navigator.userAgent.match(/Android/i) |
|
|| navigator.userAgent.match(/webOS/i) |
|
|| navigator.userAgent.match(/iPhone/i) |
|
|| navigator.userAgent.match(/iPad/i) |
|
|| navigator.userAgent.match(/iPod/i) |
|
|| navigator.userAgent.match(/BlackBerry/i) |
|
|| navigator.userAgent.match(/Windows Phone/i) ) |
|
{ |
|
return true; |
|
} |
|
else |
|
{ |
|
return false; |
|
} |
|
} |
|
|
|
function detectBrowser() { |
|
|
|
var uni_browser = {}; |
|
var uagent = navigator.userAgent.toLowerCase(), |
|
match = ''; |
|
|
|
uni_browser.chrome = /webkit/.test(uagent) && /chrome/.test(uagent) && |
|
!/edge/.test(uagent); |
|
|
|
uni_browser.firefox = /mozilla/.test(uagent) && /firefox/.test(uagent); |
|
|
|
uni_browser.msie = /msie/.test(uagent) || /trident/.test(uagent) || |
|
/edge/.test(uagent); |
|
|
|
uni_browser.safari = /safari/.test(uagent) && /applewebkit/.test(uagent) && |
|
!/chrome/.test(uagent); |
|
|
|
uni_browser.opr = /mozilla/.test(uagent) && /applewebkit/.test(uagent) && |
|
/chrome/.test(uagent) && /safari/.test(uagent) && |
|
/opr/.test(uagent); |
|
|
|
uni_browser.version = ''; |
|
|
|
for (x in uni_browser) { |
|
if (uni_browser[x]) { |
|
|
|
match = uagent.match( |
|
new RegExp("(" + (x === "msie" ? "msie|edge" : x) + ")( |\/)([0-9]+)") |
|
); |
|
|
|
if (match) { |
|
uni_browser.version = match[3]; |
|
} else { |
|
match = uagent.match(new RegExp("rv:([0-9]+)")); |
|
uni_browser.version = match ? match[1] : ""; |
|
} |
|
break; |
|
} |
|
} |
|
uni_browser.opera = uni_browser.opr; |
|
delete uni_browser.opr; |
|
|
|
return uni_browser; |
|
} |
|
|
|
function getDefaultStreamMode() |
|
{ |
|
var browser = detectBrowser(); |
|
|
|
if ( browser.opera ) |
|
return WS_WR; |
|
else if ( browser.msie ) |
|
return WS;//Include IE and Edge 2018.07.27 Edge with Worker cause crush. |
|
else if ( browser.chrome ) |
|
return WS_WR; |
|
else if ( browser.firefox ) |
|
{ |
|
if ( browser.version >= 54.0 )//Since 54 became multi-thread base browser. |
|
return WS_WR; |
|
else |
|
return WS; |
|
} |
|
else if ( browser.safari ) |
|
return WS_WR; |
|
else |
|
return WS; |
|
} |
|
|
|
function _recvCalc() |
|
{ |
|
this.dataType = DATAH264; |
|
this.decodedTimestamp = 0; |
|
this.decodedTimespec = 0; |
|
this.decodedSpendMsec = 0; |
|
this.decodedFPS_Cnt = 0; |
|
this.lastDecodedFPS = 0; |
|
this.decodedTP = 0; |
|
this.lastDecodedTP = 0; |
|
this.width = 0; |
|
this.height = 0; |
|
this.string = ""; |
|
this.receivedTimestamp = 0; |
|
this.receivedTimespec = 0; |
|
this.receivedSpendMsec = 0; |
|
this.receivedFPS_Cnt = 0; |
|
this.lastReceivedFPS = 0; |
|
this.receivedTP = 0; |
|
this.lastReceivedTP = 0; |
|
this.receivedString = ""; |
|
this.decodedString = ""; |
|
this.latencyString = ""; |
|
this.dropedString = ""; |
|
this.iframe_bottleneck = 0; |
|
} |
|
|
|
function _codecInformation() |
|
{ |
|
this.videoType = DATAH265; |
|
this.audioType = DATATYPE_G711U; |
|
this.sampleRate = 8000; |
|
this.bitRate = 16000; |
|
this.width = 1920; |
|
this.height = 1080; |
|
this.snapshot = 0; |
|
this.recorder = 0; |
|
this.ctx = null; |
|
this.FPS = 30; |
|
this.decodeStatus = 0; |
|
this.snapshotFile = null; |
|
this.recorderFile = null; |
|
|
|
} |
|
|
|
function getDecodedCalcString( rCalc ) |
|
{ |
|
if(( rCalc.dataType == DATAH264 ) || ( rCalc.dataType == DATAJPEG ) || ( rCalc.dataType == DATAH265 )) |
|
{ |
|
//retstring =( rCalc.dataType == DATAH264 ? " H264" : " H265" ); |
|
if( rCalc.dataType == DATAH264 ) |
|
retstring =" H264"; |
|
else if( rCalc.dataType == DATAJPEG ) |
|
retstring =" JPEG"; |
|
else if( rCalc.dataType == DATAH265 ) |
|
retstring =" H265"; |
|
|
|
retstring += ( " " + rCalc.lastDecodedFPS + "FPS" ); |
|
retstring += (rCalc.width != 0 ? (" " + rCalc.width + "X" + rCalc.height):""); |
|
retstring += (" " + rCalc.decodedSpendMsec + "ms" ); |
|
//retstring += " " +Math.floor( ((rCalc.lastDecodedTP*8)/1024) ) + "Kbps"; |
|
} |
|
else |
|
{ |
|
retstring = " Unknow stream tpye"; |
|
} |
|
//console.log( retstring ); |
|
return retstring; |
|
} |
|
|
|
function getReceivedCalcString( rCalc ) |
|
{ |
|
retstring = ( " " + rCalc.lastReceivedFPS + "FPS" ); |
|
retstring += (" " + rCalc.receivedSpendMsec + "ms" ); |
|
return retstring; |
|
} |
|
|
|
function calcDecodedFpsAndTp( rCalc, frameInfo ) |
|
{ |
|
nbytes = frameInfo.nbytes; |
|
rCalc.decodedTimestamp = frameInfo.timestamp; |
|
//console.log("calcDecodedFpsAndTp rCalc.decodedTimespec:"+rCalc.decodedTimespec); |
|
if ( rCalc.decodedTimespec == 0 ) |
|
{ |
|
rCalc.decodedTimespec = new Date().getTime(); |
|
if( rCalc.decodedFPS_Cnt == 1 ) |
|
rCalc.decodedFPS_Cnt += 1; |
|
else |
|
rCalc.decodedFPS_Cnt = 1; |
|
rCalc.decodedTP = nbytes; |
|
} |
|
else |
|
{ |
|
rCalc.decodedSpendMsec = new Date().getTime() - rCalc.decodedTimespec; |
|
//console.log("calcDecodedFpsAndTp rCalc.decodedSpendMsec:"+rCalc.decodedSpendMsec); |
|
rCalc.decodedFPS_Cnt++; |
|
rCalc.decodedTP += nbytes; |
|
rCalc.width = frameInfo.width; |
|
rCalc.height = frameInfo.height; |
|
|
|
if( rCalc.decodedSpendMsec >= 1000 )//OVER 1SEC |
|
{ |
|
rCalc.decodedFPS_Cnt -= 1; |
|
rCalc.lastDecodedTP = rCalc.decodedTP - nbytes; |
|
|
|
if( rCalc.lastDecodedFPS != rCalc.decodedFPS_Cnt ) |
|
rCalc.lastDecodedFPS = rCalc.decodedFPS_Cnt; |
|
|
|
//rCalc.lastDecodedFPS = rCalc.decodedFPS_Cnt; |
|
|
|
rCalc.decodedFPS_Cnt = 1; |
|
rCalc.decodedString = getDecodedCalcString( rCalc ); |
|
rCalc.decodedTimespec = rCalc.decodedSpendMsec = 0; |
|
} |
|
} |
|
} |
|
|
|
function calcReceivedFpsAndTp( rCalc, frameInfo ) |
|
{ |
|
nbytes = frameInfo.nbytes; |
|
rCalc.receivedTimestamp = frameInfo.timestamp; |
|
//console.log("calcReceivedFpsAndTp rCalc.receivedTimespec:"+rCalc.receivedTimespec); |
|
if ( rCalc.receivedTimespec == 0 ) |
|
{ |
|
rCalc.receivedTimespec = new Date().getTime(); |
|
if( rCalc.receivedFPS_Cnt == 1 ) |
|
rCalc.receivedFPS_Cnt += 1; |
|
else |
|
rCalc.receivedFPS_Cnt = 1; |
|
rCalc.receivedTP = nbytes; |
|
} |
|
else |
|
{ |
|
rCalc.receivedSpendMsec = new Date().getTime() - rCalc.receivedTimespec; |
|
//console.log("calcReceivedFpsAndTp rCalc.receivedSpendMsec:"+rCalc.receivedSpendMsec); |
|
rCalc.receivedFPS_Cnt++; |
|
rCalc.receivedTP += nbytes; |
|
|
|
if( rCalc.receivedSpendMsec >= 1000 )//OVER 1SEC |
|
{ |
|
rCalc.receivedFPS_Cnt -= 1; |
|
rCalc.lastReceivedTP = rCalc.receivedTP - nbytes; |
|
|
|
if( rCalc.lastReceivedFPS != rCalc.receivedFPS_Cnt ) |
|
rCalc.lastReceivedFPS = rCalc.receivedFPS_Cnt; |
|
|
|
//rCalc.lastReceivedFPS = rCalc.receivedFPS_Cnt; |
|
rCalc.receivedFPS_Cnt = 1; |
|
rCalc.receivedString = getReceivedCalcString( rCalc ); |
|
rCalc.receivedTimespec = rCalc.receivedSpendMsec = 0; |
|
} |
|
} |
|
} |
|
|
|
|
|
var g_Ctx = null; |
|
var g_DecodeStatus = 0; |
|
var g_SanpShot = 0; |
|
var g_Record = 0; |
|
var g_SanpShotFile = null; |
|
var g_RecordFile = null; |
|
var g_VideoType = null; |
|
var g_AudioType = null; |
|
var g_SampleRate = null; |
|
var g_BitRate = null; |
|
var g_Fps = null; |
|
var g_Width = null; |
|
var g_Height = null; |
|
|
|
function ws_worker_close(decCore, workerNum) { |
|
decCore.ws_worker[workerNum].postMessage("close"); |
|
mywaiting(300); |
|
decCore.ws_worker[workerNum].terminate(); |
|
mywaiting(300); |
|
decCore.ws_worker[workerNum] = null; |
|
} |
|
|
|
|
|
function _codec( para ) |
|
{ |
|
var decCore = this; |
|
decCore.yuvCanvas = []; |
|
decCore.worker = []; //h.264 decoder worker. |
|
decCore.ws_worker = []; //websocket worker. |
|
decCore.ws = []; |
|
//decCore.audio_worker = []; |
|
decCore.eventSrc = []; |
|
decCore.lastJsonTimeString = ""; |
|
decCore.lastJsonTime = 0; |
|
decCore.iframeCnt = []; |
|
|
|
decCore.streamMode = getDefaultStreamMode(); |
|
decCore.isMob = isMobBs(); |
|
decCore.regServerCmdCb = []; |
|
decCore.disconnectCb = []; |
|
decCore.byte_handle = []; |
|
decCore.valid_byte_received = []; |
|
decCore.streamInfo = []; |
|
decCore.blank_timer = 0; |
|
decCore.rCalc = []; |
|
decCore.codecInfo = new _codecInformation(); |
|
decCore.calcDecodedFpsAndTp = calcDecodedFpsAndTp; |
|
decCore.calcReceivedFpsAndTp = calcReceivedFpsAndTp; |
|
decCore.dropLatencyDecoded = para.droplatencydecoded; |
|
decCore.playback_info = null; |
|
decCore.buffering_activated = false; |
|
decCore.buffering_ctrl = []; |
|
decCore.activate_buffering = function() { |
|
decCore.buffering_activated = true; |
|
}; |
|
decCore.disable_buffering = function() { |
|
decCore.buffering_activated = false; |
|
decCore.buffering_ctrl = []; |
|
}; |
|
decCore.init_ffdecodecWorker = 0; |
|
decCore.Queue = []; |
|
|
|
|
|
//decCore.h264ModuleFS = 524288; |
|
function uni_event_struct( eventType, url ) |
|
{ |
|
this.eventType = eventType; |
|
this.url = url; |
|
this.evtStatus = 0; |
|
this.evt = null; |
|
}; |
|
|
|
for ( var i = 0; i < para.worker_num; i++ ) |
|
{ |
|
decCore.eventSrc[ i ] = new uni_event_struct( 1, "" ); |
|
} |
|
|
|
decCore.para = para; |
|
decCore.refpath = window.location.origin + window.location.pathname |
|
decCore.refpath = decCore.refpath.substring( 0, decCore.refpath.lastIndexOf( "/" ) ); |
|
|
|
for ( var i = 0; i < para.worker_num; i++ ) |
|
{ |
|
//console.log("para.worker_num:"+para.worker_num+" i:"+i); |
|
decCore.para.decode[ i ] = DATAH264;//default |
|
decCore.yuvCanvas[ i ] = new YUVCanvas( { width: para.vc[ i ].width, |
|
height: para.vc[ i ].height, |
|
contextOptions: null } ); |
|
decCore.byte_handle[ i ] = true; |
|
decCore.valid_byte_received[ i ] = false; |
|
decCore.rCalc[ i ] = new _recvCalc; |
|
} |
|
decCore.init_worker = function( workerNum ) |
|
{ |
|
decCore.initDecodeWorker ( workerNum, decCore.refpath, decCore.para.vc[ workerNum ], decCore.para.decode[ workerNum ] ); |
|
}; |
|
|
|
|
|
decCore.initDecodeWorker = function ( workerNum, refpath, vc , dec ) { |
|
//hevc or h264 |
|
|
|
var tmp = function () { |
|
var waitCount = 1; |
|
var RuntimeInitializedTime = 0; |
|
importScripts( "sCriPtSrc" ); |
|
// register all compiled codecs |
|
|
|
var onRuntimeInitialized = function() |
|
{ |
|
if (typeof Module.asm == "undefined") |
|
{ |
|
console.log("typeof Module.asm == undefined\n"); |
|
waitCount++; |
|
RuntimeInitializedTime = setTimeout(onRuntimeInitialized, (1000*waitCount)); |
|
return; |
|
} |
|
|
|
this.ctx = null; |
|
this.snapshot = 0; |
|
this.recorder = 0; |
|
this.decodeOnEnd = true; |
|
this.decodedFrame = null; |
|
this._SnapShot = null; |
|
this._RecordStart = null; |
|
this._Record_Stop = null; |
|
this.objectUrl = null; |
|
var blobSelf = this; |
|
|
|
|
|
function innerWorkerDecode(e) |
|
{ |
|
blobSelf.decodeOnEnd = false; |
|
var MD = e.data; |
|
var codecinfo = MD.info; |
|
var data = MD.data; |
|
|
|
if(blobSelf.ctx == null) |
|
{ |
|
//console.log("codecinfo.audioType:"+codecinfo.audioType); |
|
blobSelf.ctx = _decode_init( |
|
codecinfo.videoType, |
|
codecinfo.audioType, |
|
codecinfo.width, |
|
codecinfo.height, |
|
codecinfo.sampleRate, |
|
codecinfo.bitRate, |
|
codecinfo.FPS); |
|
} |
|
|
|
if((codecinfo.snapshot == 0) && (blobSelf._SnapShot != null) && (blobSelf.ctx)) |
|
{ |
|
blobSelf._SnapShot = null; |
|
blobSelf.objectUrl = null; |
|
} |
|
else if((codecinfo.snapshot == 1) && (blobSelf._SnapShot == null) && (blobSelf.ctx)) |
|
{ |
|
blobSelf.snapshot++; |
|
blobSelf._SnapShot = Module.cwrap('SnapShot','number', ['number', 'string']); |
|
if(_SnapShot) |
|
var ret = blobSelf._SnapShot(blobSelf.ctx, codecinfo.snapshotFile); |
|
} |
|
|
|
if((codecinfo.recorder == 0) && (blobSelf._RecordStart != null) && (blobSelf.ctx)) |
|
{ |
|
blobSelf._RecordStart = null; |
|
blobSelf._RecordStop = null; |
|
blobSelf.objectUrl = null; |
|
} |
|
else if((codecinfo.recorder == 1) && (blobSelf._RecordStart == null) && (blobSelf.ctx)) |
|
{ |
|
//console.log("blobSelf.recorder:"+blobSelf.recorder); |
|
//console.log("worker codecinfo.recorder == 1"); |
|
blobSelf.recorder++; |
|
blobSelf._RecordStart = Module.cwrap('RecordStart','number', ['number', 'string']); |
|
if(blobSelf._RecordStart) |
|
var ret = blobSelf._RecordStart(blobSelf.ctx, codecinfo.recorderFile); |
|
} |
|
else if((blobSelf.recorder == 1) && (codecinfo.recorder == 2) && (blobSelf.ctx)) |
|
{ |
|
//console.log("blobSelf.recorder:"+blobSelf.recorder); |
|
//console.log("worker codecinfo.recorder == 2"); |
|
blobSelf._Record_Stop = Module.cwrap('Record_Stop', 'number', ['number']); |
|
if(blobSelf._Record_Stop) |
|
{ |
|
var iRet = blobSelf._Record_Stop(blobSelf.ctx); |
|
if(iRet == 0) |
|
blobSelf.recorder++; |
|
} |
|
} |
|
|
|
var av_pktData = Module._malloc(data.pktSize); |
|
Module.writeArrayToMemory( data.pktData, av_pktData); |
|
|
|
var skip = 0; |
|
var decoded_frame = null; |
|
if(blobSelf.ctx) |
|
decoded_frame = _decode_video(blobSelf.ctx, |
|
av_pktData, |
|
data.pktSize, |
|
data.dataType, |
|
skip); |
|
|
|
Module._free(av_pktData); |
|
|
|
if(decoded_frame) |
|
{ |
|
var frame_width = Module.getValue(decoded_frame + 68, 'i32'); |
|
//console.log("frame_width:"+frame_width); |
|
var frame_height = Module.getValue(decoded_frame + 72, 'i32'); |
|
//console.log("frame_height:"+frame_height); |
|
if((frame_width == 0)|| (frame_height == 0)) |
|
{ |
|
blobSelf.decodeOnEnd = true; |
|
return null; //Is audio |
|
} |
|
|
|
if ( ( frame_width == 1080 ) && ( frame_height == 1920 ) ) { |
|
frame_width = 1088; frame_height = 1920; |
|
} |
|
else if ( ( frame_width == 1944 ) && ( frame_height == 2592 ) ) { |
|
frame_width = 1952; frame_height = 2592; |
|
} |
|
|
|
if(blobSelf.snapshot > 0) |
|
{ |
|
try |
|
{ |
|
//console.log("readfile codecinfo.snapshotFile:"+codecinfo.snapshotFile); |
|
|
|
var data = Module.FS.readFile(codecinfo.snapshotFile); |
|
if(data) |
|
{ |
|
blobSelf.objectUrl = URL.createObjectURL(new Blob([data], { type: "image/jpeg" })); |
|
//console.log("snapshot objectUrl:"+objectUrl); |
|
blobSelf.snapshot = 0; |
|
} |
|
} |
|
catch (e) |
|
{ |
|
//console.log("readFile error!"); |
|
} |
|
} |
|
|
|
if((blobSelf.recorder == 2) && (codecinfo.recorder == 2)) |
|
{ |
|
try |
|
{ |
|
//console.log("blobSelf.recorder:"+blobSelf.recorder); |
|
//console.log("readfile codecinfo.recorderFile:"+codecinfo.recorderFile); |
|
|
|
var data = Module.FS.readFile(codecinfo.recorderFile); |
|
if(data) |
|
{ |
|
blobSelf.objectUrl = URL.createObjectURL(new Blob([data], { type: "video/mp4" })); |
|
//console.log("recorder objectUrl:"+objectUrl); |
|
blobSelf.recorder = 0; |
|
} |
|
} |
|
catch (e) |
|
{ |
|
//console.log("readFile error!"); |
|
} |
|
} |
|
|
|
// copy Y channel to canvas |
|
var frameYDataPtr = Module.getValue(decoded_frame, '*'); |
|
var frameUDataPtr = Module.getValue(decoded_frame + 4, '*'); |
|
var frameVDataPtr = Module.getValue(decoded_frame + 8, '*'); |
|
|
|
blobSelf.decodeOnEnd = true; |
|
|
|
return { |
|
frame_width: frame_width, |
|
frame_height: frame_height, |
|
frameYDataPtr: frameYDataPtr, |
|
frameUDataPtr: frameUDataPtr, |
|
frameVDataPtr: frameVDataPtr, |
|
frameYData: new Uint8Array(Module.HEAPU8.buffer.slice(frameYDataPtr, frameYDataPtr + frame_width * frame_height)), |
|
frameUData: new Uint8Array(Module.HEAPU8.buffer.slice(frameUDataPtr, frameUDataPtr + frame_width / 2 * frame_height / 2)), |
|
frameVData: new Uint8Array(Module.HEAPU8.buffer.slice(frameVDataPtr, frameVDataPtr + frame_width / 2 * frame_height / 2)), |
|
frameTime: null, |
|
downloadUrl: blobSelf.objectUrl, |
|
}; |
|
} |
|
else |
|
console.log("no decoded_frame"); |
|
} |
|
|
|
blobSelf.onmessage = function (e) |
|
{ |
|
if ( e.data != null ) |
|
{ |
|
var MD = e.data; |
|
var data = MD.data; |
|
var codecinfo = MD.info; |
|
|
|
|
|
if(blobSelf.decodeOnEnd == true) |
|
blobSelf.decodedFrame = innerWorkerDecode(e); |
|
|
|
if(blobSelf.decodedFrame) { |
|
//decodedFrame.frameTime = decodedFrame.frameTime; |
|
decodedFrame.downloadUrl = decodedFrame.downloadUrl, |
|
blobSelf.postMessage( blobSelf.decodedFrame, [ |
|
blobSelf.decodedFrame.frameYData.buffer, |
|
blobSelf.decodedFrame.frameUData.buffer, |
|
blobSelf.decodedFrame.frameVData.buffer, |
|
] ); |
|
} |
|
} |
|
} |
|
} |
|
RuntimeInitializedTime = setTimeout(onRuntimeInitialized, 1000); |
|
|
|
}.toString(); |
|
|
|
var tmp2 = tmp.replace( "sCriPtSrc", ( refpath + "/unit3.js" )); |
|
var tmp3 = tmp2.replace( "asmjsdecode", ( ( dec == DATAH264 ) ? "h264" : "hevc" ) ); |
|
var tmp4 = tmp3.replace( "_pktDataSize_", ( ( detectBrowser().safari ) ? 524288 : 1048576 ) ); |
|
tmp = tmp2 = tmp3 = null; |
|
var blob = new Blob( [ '(',tmp4, ')()' ],{ type: 'text/javascript' } ); |
|
var blobURL = window.URL.createObjectURL( blob ); |
|
decCore.worker[ workerNum ] = new Worker( blobURL ); |
|
|
|
//Original Version |
|
decCore.worker[ workerNum ].onmessage = function (e) { |
|
var skip = 0; |
|
var decodedFrame = e.data; |
|
|
|
try |
|
{ |
|
//console.log("decCore.codecInfo.snapshot:"+decCore.codecInfo.snapshot); |
|
if(decCore.codecInfo.snapshot == 1) |
|
{ |
|
//console.log("decodedFrame.downloadUrl:"+decodedFrame.downloadUrl); |
|
if((decodedFrame.downloadUrl != "") && (decodedFrame.downloadUrl != undefined)) |
|
{ |
|
const objectUrl = decodedFrame.downloadUrl;//URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); |
|
const a = document.createElement('a'); |
|
a.setAttribute('href', objectUrl); |
|
a.setAttribute('download', decCore.codecInfo.snapshotFile); |
|
document.body.appendChild(a); |
|
a.click(); |
|
document.body.removeChild(a); |
|
decCore.codecInfo.snapshot = 0; |
|
decCore.codecInfo.snapshotFile = null; |
|
} |
|
} |
|
} |
|
catch (e) |
|
{ |
|
console.log("download error!"); |
|
} |
|
|
|
try |
|
{ |
|
//console.log("decCore.codecInfo.recorder:"+decCore.codecInfo.recorder); |
|
if(decCore.codecInfo.recorder == 2) |
|
{ |
|
//console.log("decodedFrame.downloadUrl:"+decodedFrame.downloadUrl); |
|
if((decodedFrame.downloadUrl != "") && (decodedFrame.downloadUrl != undefined)) |
|
{ |
|
const objectUrl = decodedFrame.downloadUrl;//URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); |
|
const a = document.createElement('a'); |
|
a.setAttribute('href', objectUrl); |
|
a.setAttribute('download', decCore.codecInfo.recorderFile); |
|
document.body.appendChild(a); |
|
a.click(); |
|
document.body.removeChild(a); |
|
decCore.codecInfo.recorder = 0; |
|
decCore.codecInfo.recorderFile = null; |
|
} |
|
} |
|
} |
|
catch (e) |
|
{ |
|
console.log("download error!"); |
|
} |
|
|
|
|
|
if (!decCore.resetCalled) { |
|
if(decodedFrame) |
|
{ |
|
decodedFrame.frameTime = decodedFrame.pktTime; |
|
decCore.yuvCanvas[ workerNum ].canvasElement.drawing = true; |
|
decCore.yuvCanvas[ workerNum ].drawNextOuptutPictureGL({ |
|
yData: decodedFrame.frameYData, |
|
yDataPerRow: decodedFrame.frame_width, |
|
yRowCnt: decodedFrame.frame_height, |
|
uData: decodedFrame.frameUData, |
|
uDataPerRow: decodedFrame.frame_width / 2, |
|
uRowCnt: decodedFrame.frame_height / 2, |
|
vData: decodedFrame.frameVData, |
|
vDataPerRow: decodedFrame.frame_width / 2, |
|
vRowCnt: decodedFrame.frame_height / 2 |
|
}); |
|
decCore.yuvCanvas[ workerNum ].canvasElement.drawing = false; |
|
decCore.calcDecodedFpsAndTp( decCore.rCalc[ workerNum ], { width: decodedFrame.frame_width, height: decodedFrame.frame_height, nbytes: 0, timestamp: decodedFrame.frameTime } ); |
|
} |
|
} |
|
|
|
};//.bind( decCore ); /*seems not effect diable*/ |
|
|
|
decCore.worker[ workerNum ].onclose = function () |
|
{ |
|
console.log('Your worker instance has been closed'); |
|
}; |
|
decCore.worker[ workerNum ].onerror = function () |
|
{ |
|
decCore.init_worker( workerNum );//retry |
|
}; |
|
|
|
// Won't be needing this anymore //Edge can't revoke |
|
//window.URL.revokeObjectURL(blobURL); |
|
}; |
|
|
|
|
|
//function innerWorkerDecode2(pktSize, pktData, dataType) |
|
function innerWorkerDecode2() |
|
{ |
|
try |
|
{ |
|
if(decCore.codecInfo.snapshot) |
|
{ |
|
console.log("read file 1"); |
|
console.log("file name:"+decCore.codecInfo.snapshotFile); |
|
var data = Module.FS.readFile(decCore.codecInfo.snapshotFile); |
|
console.log("read file 2"); |
|
if(data) |
|
{ |
|
console.log("read file 3"); |
|
const objectUrl = URL.createObjectURL(new Blob([data], { type: "image/jpeg" }));//URL.createObjectURL(blob); |
|
console.log("read file 4"); |
|
const a = document.createElement('a'); |
|
console.log("read file 5"); |
|
a.setAttribute('href', objectUrl); |
|
console.log("read file 6"); |
|
a.setAttribute('download', decCore.codecInfo.snapshotFile); |
|
console.log("read file 7"); |
|
document.body.appendChild(a); |
|
console.log("read file 8"); |
|
a.click(); |
|
console.log("read file 9"); |
|
document.body.removeChild(a); |
|
console.log("read file 10"); |
|
decCore.codecInfo.snapshotFile = null; |
|
decCore.codecInfo.snapshot = 0; |
|
} |
|
} |
|
} |
|
catch (e) |
|
{ |
|
console.log("readFile error!"); |
|
} |
|
|
|
/* |
|
var av_pktData = Module._malloc(pktSize); |
|
Module.writeArrayToMemory( pktData, av_pktData); |
|
|
|
|
|
|
|
var decoded_frame = null; |
|
//console.log("innerWorkerDecode2 pktSize2:"+pktSize); |
|
//console.log("innerWorkerDecode2 avType:"+ avType+" dataType:"+dataType); |
|
|
|
|
|
if((g_Ctx) && g_DecodeStatus == 2) |
|
{ |
|
//console.log("decCore.DecodeClose"); |
|
//_decode_close(g_Ctx); |
|
g_VideoType = g_AudioType = g_Width = g_Height = g_SampleRate = g_BitRate = g_Fps = 0; |
|
g_Ctx = null; |
|
} |
|
else if((g_Ctx) && g_DecodeStatus != 2) |
|
{ |
|
decoded_frame = _decode_video(g_Ctx, av_pktData, pktSize, dataType); |
|
} |
|
else if(g_DecodeStatus == 1) |
|
{ |
|
console.log("g_Ctx:"+g_Ctx+" g_DecodeStatus:"+g_DecodeStatus); |
|
//if((g_Width > 0) && (g_Height > 0) && (g_Ctx == null) && (g_DecodeStatus == 1)) |
|
g_Ctx = _decode_init(3, 5, 1920, 1080, 32000, 16000, 30, 0); |
|
|
|
if(g_Ctx) |
|
{ |
|
console.log("get g_Ctx"); |
|
g_DecodeStatus = 3; |
|
} |
|
} |
|
|
|
if(decoded_frame) |
|
{ |
|
var frame_width = Module.getValue(decoded_frame + 68, 'i32'); |
|
var frame_height = Module.getValue(decoded_frame + 72, 'i32'); |
|
if((frame_width == 0)|| (frame_height == 0)) |
|
return null; |
|
|
|
if ( ( frame_width == 1080 ) && ( frame_height == 1920 ) ) { |
|
frame_width = 1088; frame_height = 1920; |
|
} |
|
else if ( ( frame_width == 1944 ) && ( frame_height == 2592 ) ) { |
|
frame_width = 1952; frame_height = 2592; |
|
} |
|
|
|
// copy Y channel to canvas |
|
var frameYDataPtr = Module.getValue(decoded_frame, '*'); |
|
var frameUDataPtr = Module.getValue(decoded_frame + 4, '*'); |
|
var frameVDataPtr = Module.getValue(decoded_frame + 8, '*'); |
|
|
|
return { |
|
frame_width: frame_width, |
|
frame_height: frame_height, |
|
frameYDataPtr: frameYDataPtr, |
|
frameUDataPtr: frameUDataPtr, |
|
frameVDataPtr: frameVDataPtr, |
|
frameYData: new Uint8Array(Module.HEAPU8.buffer.slice(frameYDataPtr, frameYDataPtr + frame_width * frame_height)), |
|
frameUData: new Uint8Array(Module.HEAPU8.buffer.slice(frameUDataPtr, frameUDataPtr + frame_width / 2 * frame_height / 2)), |
|
frameVData: new Uint8Array(Module.HEAPU8.buffer.slice(frameVDataPtr, frameVDataPtr + frame_width / 2 * frame_height / 2)), |
|
frameTime: null, |
|
}; |
|
} |
|
|
|
Module._free(av_pktData);*/ |
|
}; |
|
|
|
|
|
decCore.DecodeInit = function(Video_type, Audio_type, width, height, fps, sample_rate, bit_rate) |
|
{ |
|
console.log("width:"+width+" height:"+height+" fps:"+fps); |
|
//console.log("Video_type:%d, Audio_type:%d, sample_rate:%d, bit_rate:%d\n", Video_type, Audio_type, sample_rate, bit_rate); |
|
decCore.codecInfo.videoType = Video_type; |
|
decCore.codecInfo.audioType = DATATYPE_G711U; //Set audio type always MULAW by Sue, 2023/11/20 |
|
decCore.codecInfo.width = width; |
|
decCore.codecInfo.height = height; |
|
decCore.codecInfo.FPS = fps; |
|
decCore.codecInfo.sampleRate = sample_rate; |
|
decCore.codecInfo.bitRate = bit_rate; |
|
decCore.codecInfo.decodeStatus = 1; |
|
g_DecodeStatus = 1; |
|
}; |
|
|
|
|
|
decCore.DecodeClose = function() |
|
{ |
|
decCore.codecInfo.decodeStatus = 2; |
|
} |
|
|
|
|
|
decCore.SnapShot = function() |
|
{ |
|
var todays = new Date(); |
|
decCore.codecInfo.snapshotFile = String(todays.getFullYear())+('0'+String(eval(parseInt(todays.getMonth())+1))).substr(-2)+('0'+String(todays.getDate())).substr(-2)+('0'+String(todays.getHours())).substr(-2)+('0'+String(todays.getMinutes())).substr(-2)+('0'+String(todays.getSeconds())).substr(-2)+".jpeg"; |
|
//console.log("SnapShot filename:" + decCore.codecInfo.snapshotFile); |
|
decCore.codecInfo.snapshot = 1; |
|
//console.log("snapshot decCore.codecInfo.snapshot:"+decCore.codecInfo.snapshot); |
|
}; |
|
|
|
decCore.RecordStart = function() |
|
{ |
|
console.log("RecordStart"); |
|
var todays = new Date(); |
|
decCore.codecInfo.recorderFile = String(todays.getFullYear())+('0'+String(eval(parseInt(todays.getMonth())+1))).substr(-2)+('0'+String(todays.getDate())).substr(-2)+('0'+String(todays.getHours())).substr(-2)+('0'+String(todays.getMinutes())).substr(-2)+('0'+String(todays.getSeconds())).substr(-2)+".mp4"; |
|
decCore.codecInfo.recorder = 1; |
|
}; |
|
|
|
|
|
decCore.RecordStop = function() |
|
{ |
|
decCore.codecInfo.recorder = 2; |
|
}; |
|
|
|
decCore.decodeWorker = function ( workerNum, pktSize, pktData, pktTime, pktType, dataType) { |
|
var ret = 0; |
|
|
|
var transferableData = { |
|
pktTime: typeof pktTime != "undefined" ? pktTime : 0, |
|
pktSize: pktSize, |
|
pktData: pktData, |
|
byteOffset:pktData.byteOffset, |
|
dataType: dataType, |
|
|
|
} |
|
|
|
//console.log("decodeWorker dataType:"+dataType+" pktData:"+pktData); |
|
/*if((dataType == DATAH264) || (dataType == DATAH265) || (dataType == DATAJPEG)) |
|
{ |
|
decCore.calcReceivedFpsAndTp( decCore.rCalc[ workerNum ], { nbytes: pktSize, timestamp: typeof pktTime != "undefined" ? pktTime : 0 } ); |
|
|
|
//Checking the decoded calc |
|
{ |
|
if ( decCore.rCalc[ workerNum ].decodedTimestamp == 0 )//Not any decoded yet, so we should only feed the i frame |
|
{ |
|
//console.log("pktType:"+pktType); |
|
if ((pktType != FRAME_I) && (dataType != DATAJPEG)) |
|
return ret; |
|
} |
|
else |
|
{ |
|
_latency = decCore.rCalc[ workerNum ].receivedTimestamp - decCore.rCalc[ workerNum ].decodedTimestamp; |
|
//console.log( "decCore.decodeWorker decCore.rCalc[ "+workerNum+" ].receivedTimestamp:" + decCore.rCalc[ workerNum ].receivedTimestamp ); |
|
//console.log( "decCore.decodeWorker decCore.rCalc[ "+workerNum+" ].decodedTimestamp:" + decCore.rCalc[ workerNum ].decodedTimestamp ); |
|
decCore.rCalc[ workerNum ].latencyString = _latency + "ms"; |
|
if ( decCore.dropLatencyDecoded == true ) |
|
{ |
|
if ( _latency > 2000 )//Over 2 second |
|
{ |
|
decCore.rCalc[ workerNum ].iframe_bottleneck = 10; |
|
//console.log( "decode latency:" + _latency ); |
|
} |
|
|
|
if ( decCore.rCalc[ workerNum ].iframe_bottleneck ) |
|
{ |
|
//console.log("pktType:"+pktType); |
|
if ( pktType != FRAME_I ) |
|
{ |
|
//console.log("pktType != FRAME_I"); |
|
//return ret; |
|
} |
|
else |
|
decCore.rCalc[ workerNum ].iframe_bottleneck -= 1; |
|
} |
|
} |
|
} |
|
} |
|
}*/ |
|
|
|
//2017.03.06 for browser |
|
//original |
|
//console.log( "decCore.worker[" + workerNum + "].porstMessage" ); |
|
if ( ( decCore.worker[ workerNum ] != null ) && ( decCore.worker[ workerNum ] != "undefined" ) && ( typeof( decCore.worker[ workerNum ] ) != "undefined" ) ) |
|
decCore.worker[ workerNum ].postMessage( { 'info': decCore.codecInfo, 'data': transferableData } ); |
|
else |
|
ret = -1; |
|
|
|
return ret; |
|
}; |
|
|
|
decCore.reg_server_cmd_cb = function ( cmd_name, cb_func ) |
|
{ |
|
//console.log("cmd_name:"+cmd_name); |
|
//{ multiswitchcmd: "wslivecmd?switch&streamtype=0&channel=" + ( i < 10 ? ("0" + i):i ), singleswitchcmd: "wslivecmd?switch&streamtype=1&channel=" + ( i < 10 ? ("0" + i):i )}; |
|
var reg_item = { name: "", func: function(){}, }; |
|
reg_item.name = cmd_name; |
|
reg_item.func = cb_func; |
|
|
|
if ( decCore.regServerCmdCb.length ) |
|
{ |
|
for ( var i = 0; i < decCore.regServerCmdCb.length; i++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ i ].name == cmd_name ) |
|
return; |
|
} |
|
} |
|
|
|
decCore.regServerCmdCb[ decCore.regServerCmdCb.length ] = reg_item; |
|
}; |
|
|
|
decCore.rm_certain_server_cmd_cb = function ( cmd_name ) |
|
{ |
|
for( var search_cnt = 0; search_cnt < decCore.regServerCmdCb.length; search_cnt++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ search_cnt ].name == cmd_name ) |
|
decCore.regServerCmdCb.splice( search_cnt, 1 ); |
|
} |
|
}; |
|
|
|
decCore.rm_server_cmd_cb = function() |
|
{ |
|
console.log("decCore.rm_server_cmd_cb"); |
|
decCore.regServerCmdCb = []; |
|
}; |
|
|
|
decCore.drawBlank = function( workerNum ) |
|
{ |
|
var nodata = new Uint8Array(1); |
|
decCore.yuvCanvas[ workerNum ].drawNextOuptutPictureGL({ |
|
yData: nodata, |
|
yDataPerRow: 1, |
|
yRowCnt: 1, |
|
uData: nodata, |
|
uDataPerRow: 1, |
|
uRowCnt: 1, |
|
vData: nodata, |
|
vDataPerRow: 1, |
|
vRowCnt: 1 |
|
}); |
|
decCore.rCalc[ workerNum ] = new _recvCalc; |
|
decCore.rCalc[ workerNum ].dataType = decCore.para.decode[ workerNum ]; |
|
}; |
|
|
|
decCore.terminate_worker = function( workerNum ) |
|
{ |
|
try{ |
|
if ( decCore.worker[ workerNum ] != null ) |
|
{ |
|
if ( decCore.ws_worker[ workerNum ] != "undefined" ) |
|
{ |
|
if ( typeof( decCore.worker[ workerNum ] ) != "undefined" ) |
|
decCore.worker[ workerNum ].terminate(); |
|
} |
|
} |
|
decCore.worker[ workerNum ] = null; |
|
} |
|
catch(e) |
|
{ |
|
console.log( "Catch error terminate_worker:" + workerNum ); |
|
}; |
|
}; |
|
|
|
decCore.ws_send = function( workerNum, val ) |
|
{ |
|
switch ( decCore.streamMode ) |
|
{ |
|
case WS: |
|
{ |
|
if (( decCore.ws[ workerNum ] != null ) && ( decCore.ws[ workerNum ] != "undefined" )) |
|
{ |
|
if( typeof val == "string" ) |
|
{ |
|
decCore.ws[ workerNum ].send( val ); |
|
} |
|
} |
|
} |
|
break; |
|
case WS_WR: |
|
{ |
|
if (( decCore.ws_worker[ workerNum ] != null ) && ( decCore.ws_worker[ workerNum ] != "undefined" )) |
|
{ |
|
if ( typeof val == "string" ) |
|
decCore.ws_worker[ workerNum ].postMessage( val ); |
|
} |
|
} |
|
break; |
|
} |
|
}; |
|
|
|
decCore.disable_byte_handle = function( workerNum ) |
|
{ |
|
decCore.byte_handle[ workerNum ] = false; |
|
if ( decCore.dropLatencyDecoded == true ) { |
|
decCore.rCalc[ workerNum ] = new _recvCalc; |
|
if ( decCore.iframeCnt[ workerNum ] <= 0 ) |
|
decCore.iframeCnt[ workerNum ] = 1; |
|
} |
|
}; |
|
decCore.enable_byte_handle = function( workerNum ) |
|
{ |
|
decCore.byte_handle[ workerNum ] = true; |
|
}; |
|
decCore.get_recv_information = function( workerNum ) |
|
{ |
|
return decCore.rCalc[ workerNum ].receivedString; |
|
}; |
|
decCore.get_dec_information = function( workerNum ) |
|
{ |
|
return decCore.rCalc[ workerNum ].decodedString; |
|
}; |
|
decCore.get_latency_information = function( workerNum ) |
|
{ |
|
return decCore.rCalc[ workerNum ].latencyString; |
|
}; |
|
|
|
decCore.switch_event = function( workerNum, eventType ) |
|
{ |
|
|
|
{ |
|
decCore.eventSrc[ workerNum ].eventType = eventType |
|
switch( decCore.streamMode ) |
|
{ |
|
case WS: |
|
{ |
|
switch ( eventType ) |
|
{ |
|
case P_ONE_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
case P_MLT_DEC_MLT_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; |
|
break; |
|
case P_MLT_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; |
|
break; |
|
case S_ONE_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
} |
|
} |
|
break; |
|
case WS_WR: |
|
{ |
|
if ( decCore.ws_worker[ workerNum ] == null ) |
|
{ |
|
console.log( workerNum + " ws_worker is null!" ); |
|
return; |
|
} |
|
switch ( eventType ) |
|
{ |
|
case P_ONE_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
case P_MLT_DEC_MLT_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; |
|
break; |
|
case P_MLT_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; |
|
break; |
|
case S_ONE_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
} |
|
} |
|
break; |
|
} |
|
} |
|
}; |
|
|
|
decCore.init_event = function ( eventType, workerNum, url ){ |
|
//console.log( "init_event: " + workerNum ); |
|
decCore.eventSrc[ workerNum ].url = url; |
|
decCore.eventSrc[ workerNum ].eventType = eventType; |
|
|
|
if ( decCore.isMob ) |
|
{ |
|
decCore.iframeCnt[ workerNum ] = 1; |
|
} |
|
else |
|
{ |
|
decCore.iframeCnt[ workerNum ] = 1; |
|
} |
|
|
|
switch ( decCore.streamMode ) |
|
{ |
|
case WS: |
|
{ |
|
var wspath = window.location.origin; |
|
if ( wspath.indexOf( "https" ) != -1 ) |
|
wspath = wspath.replace( "https", "wss" ); |
|
else |
|
wspath = wspath.replace( "http", "ws" ); |
|
|
|
decCore.ws[ workerNum ] = new WebSocket( ( wspath + ( url.substring( url.indexOf( "/"), url.length ) ) ) ); |
|
decCore.ws[ workerNum ].binaryType = 'arraybuffer'; |
|
switch ( eventType ) |
|
{ |
|
case P_ONE_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
case P_MLT_DEC_MLT_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; |
|
break; |
|
case P_MLT_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; |
|
break; |
|
case S_ONE_DEC_ONE_WS: |
|
decCore.ws[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
} |
|
|
|
decCore.ws[ workerNum ].onerror = function () { |
|
try { |
|
//if ( navigator.userAgent != "Firefox" ) |
|
// decCore.ws[ workerNum ].send( "wsclose" ); |
|
mywaiting( 300 ); |
|
decCore.ws[ workerNum ].close(); |
|
mywaiting( 300 ); |
|
decCore.ws[ workerNum ] = null; |
|
}catch(e){}; |
|
} |
|
mywaiting( 100 ); |
|
} |
|
break; |
|
case WS_WR: |
|
{ |
|
var ws_blob_str = function() |
|
{ |
|
var ws = null; |
|
var ws_blob = this; |
|
this.onmessage = function ( e ) |
|
{ |
|
if ( e.data.search( "close" ) != -1 ) |
|
{ |
|
console.log( e.data ); |
|
ws.send("wsclose"); |
|
} |
|
else if ( e.data.search( "wsplaybackcmd" ) != -1 ) |
|
{ |
|
console.log( e.data ); |
|
ws.send( e.data ); |
|
} |
|
else if ( e.data.search( "wslivecmd") != -1 ) |
|
{ |
|
console.log( e.data ); |
|
ws.send( e.data ); |
|
} |
|
else |
|
{ |
|
console.log( e.data ); |
|
init( e.data ); |
|
} |
|
}; |
|
function init( url ) |
|
{ |
|
ws = new WebSocket( url ); |
|
ws.binaryType = 'arraybuffer'; |
|
ws.onmessage = function ( e ) |
|
{ |
|
ws_blob.postMessage( e.data ); |
|
} |
|
ws.onerror = function ( e ) |
|
{ |
|
ws_blob.postMessage( "wsonerror" ); |
|
try{ |
|
//ws.send("wsclose"); |
|
ws.close(); |
|
}catch(e){}; |
|
} |
|
ws.onclose = function ( e ) |
|
{ |
|
//setTimeout(function () { |
|
ws_worker_close(decCore, workerNum); |
|
//}, 1000); |
|
} |
|
} |
|
}.toString(); |
|
var blob = new Blob( [ '(',ws_blob_str, ')()' ],{ type: 'text/javascript' } ); |
|
var blobURL = window.URL.createObjectURL( blob ); |
|
decCore.ws_worker[ workerNum ] = new Worker( blobURL ); |
|
|
|
var wspath = window.location.origin; |
|
if ( wspath.indexOf( "https" ) != -1 ) |
|
wspath = wspath.replace( "https", "wss" ); |
|
else |
|
wspath = wspath.replace( "http", "ws" ); |
|
|
|
decCore.ws_worker[ workerNum ].postMessage( ( wspath + ( url.substring( url.indexOf( "/"), url.length ) ) ) );//start websocket |
|
switch ( eventType ) |
|
{ |
|
case P_ONE_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
case P_MLT_DEC_MLT_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_multi_ws_wr; |
|
break; |
|
case P_MLT_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.multi_dec_wr_one_ws_wr; |
|
break; |
|
case S_ONE_DEC_ONE_WS: |
|
decCore.ws_worker[ workerNum ].onmessage = decCore.one_dec_wr_one_ws_wr; |
|
break; |
|
} |
|
|
|
decCore.ws_worker[ workerNum ].onerror = function ( e ) { |
|
//console.log( e ); |
|
try{ |
|
//console.log( "workerNum:" + workerNum + " onerror" ); |
|
ws_worker_close(decCore, workerNum); |
|
decCore.init_event(eventType, workerNum, url); |
|
}catch(e){}; |
|
} |
|
} |
|
break; |
|
case SES: |
|
{ |
|
decCore.eventSrc[ workerNum ].evt = new EventSource( url ); |
|
|
|
switch ( eventType ) |
|
{ |
|
case P_ONE_DEC_ONE_WS: |
|
decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleWorkerEvt; |
|
break; |
|
case P_MLT_DEC_MLT_WS: |
|
decCore.eventSrc[ workerNum ].evt.onmessage = decCore.multiWorkerEvt; |
|
break; |
|
case P_MLT_DEC_ONE_WS: |
|
decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleEvtMultiWorkerJSONContent; |
|
break; |
|
case S_ONE_DEC_ONE_WS: |
|
decCore.eventSrc[ workerNum ].evt.onmessage = decCore.singleEvtWorkerJSONContent; |
|
break; |
|
} |
|
|
|
decCore.eventSrc[ workerNum ].evt.onerror = function( event ) |
|
{ |
|
//console.log( "onerror: " + this.url ); |
|
var txt; |
|
if( ( typeof( event ) != "undefined" ) && ( event != null ) && ( typeof( event.target ) != "undefined" ) && ( event.target != null ) ) |
|
{ |
|
switch( event.target.readyState ){ |
|
// if reconnecting |
|
case EventSource.CONNECTING: |
|
txt = "Reconnect...."; |
|
break; |
|
// if error was fatal |
|
case EventSource.CLOSED: |
|
txt = "Closed, will not retry."; |
|
//close event connection |
|
event.target.onmessage = null; |
|
event.target.close(); |
|
break; |
|
} |
|
} |
|
}; |
|
//decCore.eventSrc[ workerNum ].evt.onopen = function( ) |
|
//{ |
|
// console.log( "Onopen: " + this ); |
|
//}; |
|
} |
|
break; |
|
} |
|
}; |
|
|
|
decCore.blank_timer_proc = function() |
|
{ |
|
if ( decCore.blank_timer ) |
|
{ |
|
clearTimeout( decCore.blank_timer ); |
|
} |
|
for( var i = 0; i < decCore.para.worker_num; i++ ) |
|
{ |
|
if ( decCore.valid_byte_received[ i ] == true ) |
|
decCore.valid_byte_received[ i ] = false; |
|
else |
|
{ |
|
if ( decCore.byte_handle[ i ] ) |
|
decCore.drawBlank( i ); |
|
} |
|
} |
|
decCore.blank_timer = setTimeout( decCore.blank_timer_proc, 1000 ); |
|
}; |
|
|
|
decCore.init_blank_timer = function() |
|
{ |
|
if ( decCore.blank_timer == 0 ) |
|
decCore.blank_timer = setTimeout( decCore.blank_timer_proc, 1000 ); |
|
}; |
|
|
|
decCore.delete_blank_timer = function() |
|
{ |
|
if ( decCore.blank_timer ) |
|
{ |
|
clearTimeout( decCore.blank_timer ); |
|
decCore.blank_timer = 0; |
|
} |
|
}; |
|
|
|
decCore.terminate_event = function ( workerNum, blank ){ |
|
try{ |
|
if ( decCore.ws.length > workerNum ) |
|
{ |
|
if ( decCore.ws[ workerNum ] != null ) |
|
{ |
|
if ( decCore.ws[ workerNum ] != "undefined" ) |
|
{ |
|
if ( typeof( decCore.ws[ workerNum ] ) != "undefined" ) |
|
{ |
|
console.log( "ws close: " + workerNum ); |
|
//decCore.ws[ workerNum ].send("wsclose"); |
|
mywaiting( 300 ); |
|
decCore.ws[ workerNum ].close(); |
|
mywaiting( 300 ); |
|
decCore.ws[ workerNum ] = null; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ( decCore.ws_worker.length > workerNum ) |
|
{ |
|
if ( decCore.ws_worker[ workerNum ] != null ) |
|
{ |
|
if ( decCore.ws_worker[ workerNum ] != "undefined" ) |
|
{ |
|
if ( typeof( decCore.ws_worker[ workerNum ] ) != "undefined" ) |
|
{ |
|
decCore.ws_worker[ workerNum ].postMessage( "close" ); |
|
mywaiting( 300 ); |
|
decCore.ws_worker[ workerNum ].terminate(); |
|
mywaiting( 300 ); |
|
decCore.ws_worker[ workerNum ] = null; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ( decCore.eventSrc.length > workerNum ) |
|
{ |
|
if ( decCore.eventSrc[ workerNum ] != null ) |
|
{ |
|
if ( decCore.eventSrc[ workerNum ] != "undefined" ) |
|
{ |
|
if ( ( decCore.eventSrc[ workerNum ].evt )&&( typeof( decCore.eventSrc[ workerNum ].evt ) == "object" ) ) |
|
{ |
|
decCore.eventSrc[ workerNum ].evt.close(); |
|
decCore.eventSrc[ workerNum ].evt.onmessage = null; |
|
decCore.eventSrc[ workerNum ].evt = null; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if( ( typeof( blank ) != "undefined" ) ) |
|
{ |
|
if ( blank == 1 ) |
|
decCore.drawBlank( workerNum ); |
|
} |
|
else |
|
decCore.drawBlank( workerNum ); |
|
|
|
if ( decCore.buffering_activated ) |
|
decCore.buffering_ctrl = []; |
|
} |
|
catch(e) |
|
{ |
|
console.log( "terminate_event error:" + workerNum ); |
|
}; |
|
}; |
|
|
|
decCore.isUniH264Data = function ( byte ) |
|
{ |
|
console.log( "0x" + byte[0].toString(16) + byte[1].toString(16) + byte[2].toString(16) + byte[3].toString(16) + byte[4].toString(16) ); |
|
var ret = false; |
|
var header = new Uint8Array( 3 ); |
|
header[ 0 ] = byte[ 4 ] & 0x0F; |
|
//console.log( "shift index:" + header[ 0 ].toString(16) ); |
|
//console.log( "frame type:" + byte[ header[ 0 ] ].toString(16) ); |
|
header[ 1 ] = ~( byte[ header[ 0 ] ] ); |
|
//console.log( "~frame type:" + header[ 1 ].toString(16) ); |
|
header[ 2 ] = ( header[ 1 ] >> ( header[ 0 ] )) | header[ 1 ] << ( 8 - ( header[ 0 ] ) ); |
|
//console.log( "result:" + header[ 2 ].toString(16) ); |
|
|
|
switch( header[ 2 ] ) |
|
{ |
|
case 0x21: |
|
case 0x41: |
|
case 0x61: |
|
case 0x67: |
|
case 0x68: |
|
case 0x65: |
|
case 0x27: |
|
case 0x28: |
|
case 0x25: |
|
byte[ 4 ] = header[ 2 ]; |
|
byte[ 0 ] = byte[ 1 ] = byte[ 2 ] = 0x0; |
|
byte[ 3 ] = 0x01; |
|
ret = true; |
|
break; |
|
} |
|
//console.log( "0x" + byte[0].toString(16) + byte[1].toString(16) + byte[2].toString(16) + byte[3].toString(16) + byte[4].toString(16) ); |
|
return ret; |
|
}; |
|
|
|
decCore.singleEvtWorkerJSONContent = function ( event ) |
|
{ |
|
console.log("singleEvtWorkerJSONContent"); |
|
var obj = JSON.parse( event.data ); |
|
decCore.lastJsonTimeString = obj.time; |
|
if ( ( obj.h264 ) && ( ( typeof( obj.h264 ) != "undefined" ) ) ) |
|
{ |
|
console.log("obj.h264:"+obj.h264); |
|
var byte = parseHexString( obj.h264 ); |
|
if ( decCore.isUniH264Data( byte ) ) |
|
decCore.decodeWorker( 0 , byte.length, byte ); |
|
} |
|
}; |
|
|
|
decCore.one_dec_wr_one_ws_wr = function ( e ) |
|
{ |
|
if ( typeof e.data == "string" ) |
|
{ |
|
var dataType; |
|
var dataSize; |
|
var dataBuffer; |
|
var frame_timestamp = Date.now(); |
|
//console.log("e.data:"+e.data); |
|
if ( e.data == "wsonerror" ) |
|
{ |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
else if ( e.data.search( "wsservercmd?" ) != -1 )////from server |
|
{ |
|
var cmd = e.data.replace( "wsservercmd?", "" ); |
|
//console.log("cmd: "+cmd); |
|
var cmdarray = cmd.split( "&" ); |
|
for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) |
|
{ |
|
var cmditem = cmdarray[ cmdcount ].split( "=" ); |
|
//console.log("cmdcount:"+cmdcount+" cmditem[0]: "+cmditem[0]); |
|
//console.log("cmdcount:"+cmdcount+" cmditem[1]: "+cmditem[1]); |
|
if(cmditem[1].search("G711") != -1) |
|
{ |
|
//console.log("search G711"); |
|
//dataType = DATAG711U; |
|
dataType = DATATYPE_G711U; |
|
} |
|
else if(cmditem[1].search("AAC") != -1) |
|
{ |
|
//console.log("search AAC"); |
|
//dataType = DATAAAC; |
|
dataType = DATATYPE_AAC; |
|
} |
|
|
|
|
|
if(cmditem[0].search("audio_0_type") != -1) |
|
{ |
|
dataSize = cmditem[1].length; |
|
dataBuffer = cmditem[1]; |
|
//console.log("audio_0_type Buffer:"+dataBuffer); |
|
//console.log("audio_0_type Size:"+dataSize); |
|
} |
|
|
|
if(cmditem[0].search("audio_0_data") != -1) |
|
{ |
|
//console.log("cmditem[1]:"+cmditem[1]); |
|
g_totalAudioData += cmditem[1]; |
|
//if (g_totalAudioData.length < ( AUDIO_LOWWATER ) ) |
|
//if(g_totalAudioData.length <= 2048) |
|
// return; |
|
|
|
|
|
dataBuffer = parseHexString(g_totalAudioData); |
|
dataSize = dataBuffer.length; |
|
|
|
//console.log("audio_0_data decoded:"+decoded); |
|
//console.log("audio_0_data dataSize:"+dataSize); |
|
//console.log("string decoded.length:"+decoded.length); |
|
} |
|
|
|
|
|
//now we can seach the register callback, if the name matched, put the value into the call back function |
|
for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) |
|
{ |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); |
|
} |
|
else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array |
|
{ |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem ); |
|
} |
|
} |
|
} |
|
|
|
if(dataSize > 24) |
|
{ |
|
//let form = document.querySelector('form'); |
|
//form.file.value = "D:\fakepath\audio.aac"; |
|
//let fileReader = new FileReader(); |
|
//let file = form.file.files[0]; |
|
//fileReader.readAsArrayBuffer(file); |
|
if(decCore.decodeWorker(0, dataSize, dataBuffer, frame_timestamp, 0, dataType) != 0) |
|
{ |
|
console.log( e ); |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
g_totalAudioData = ""; |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( decCore.byte_handle[ 0 ] == false ) |
|
return; |
|
|
|
var byte = new Uint8Array( e.data ); |
|
//console.log("byte:"+byte); |
|
if ( ( isHeaderPreamble( byte ) ) && ( byte.length > 24 ) ) |
|
{ |
|
var dataType = getHeaderDataType( byte ); |
|
//console.log("dataType:"+dataType); |
|
var ch_id = getHeaderId( byte ); |
|
var dec_id = 0; |
|
//var frame_type = FRAME_P; |
|
//var frame_timestamp = Date.now(); |
|
//decCore.lastJsonTime = getHeaderTime( byte ); |
|
//decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); |
|
|
|
decCore.valid_byte_received[ dec_id ] = true; |
|
|
|
if ( decCore.buffering_activated ) |
|
{ |
|
_frame_t = getHeaderTime( byte ); |
|
if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, |
|
v_times: [], |
|
a_time: 0, |
|
v_pass: false, |
|
v_array : [], }; |
|
} |
|
|
|
if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].ch = ch_id |
|
decCore.buffering_ctrl[ dec_id ].v_times = []; |
|
decCore.buffering_ctrl[ dec_id ].v_array = []; |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
return; |
|
} |
|
else |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec |
|
( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse |
|
{ |
|
byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) |
|
decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; |
|
} |
|
} |
|
|
|
var frame_timestamp = Date.now(); |
|
var frame_type = FRAME_P; |
|
|
|
dataType = getHeaderDataType( byte ); |
|
//console.log("getHeaderDataType dataType:"+dataType); |
|
ch_id = getHeaderId( byte ); |
|
decCore.lastJsonTime = getHeaderTime( byte ); |
|
decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); |
|
//dec_id = ch_id % decCore.para.worker_num; |
|
|
|
/* chirun test |
|
var saveByteArray = (function () { |
|
var a = document.createElement("a"); |
|
document.body.appendChild(a); |
|
a.style = "display: none"; |
|
return function (data, name) { |
|
var blob = new Blob(data, {type: "octet/stream"}), |
|
url = window.URL.createObjectURL(blob); |
|
a.href = url; |
|
a.download = name; |
|
a.click(); |
|
window.URL.revokeObjectURL(url); |
|
}; |
|
}()); |
|
*/ |
|
|
|
|
|
if ( dataType == DATAH264 ) |
|
{ |
|
//console.log("dataType == DATAH264"); |
|
//console.log(byte.slice( 24 )); |
|
|
|
/* |
|
g_rec.push(byte.slice( 24 )); |
|
g_rec.push(byte.slice( 24 )); |
|
|
|
if(g_rec.length> 300) |
|
{ |
|
console.log("g_rec.length " + g_rec.length); |
|
saveByteArray(g_rec, 'example.h264'); |
|
g_rec.length = 0; |
|
} |
|
*/ |
|
|
|
decCore.rCalc[ 0 ].dataType = DATAH264; |
|
if ( decCore.para.decode[ 0 ] != DATAH264 ) |
|
{ |
|
decCore.terminate_worker( 0 ); |
|
decCore.para.decode[ 0 ] = DATAH264; |
|
decCore.init_worker( 0 ); |
|
} |
|
|
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
if ( byte[ 28 ] == 0x67 ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ 0 ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + 0 + "ch_id: " + ch_id );s |
|
console.log("decCore.iframeCnt[ 0 ]:"+decCore.iframeCnt[ 0 ]); |
|
decCore.iframeCnt[ 0 ] -= 1; |
|
if ( decCore.iframeCnt[ 0 ] > 0 ) |
|
return; |
|
|
|
|
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type , dataType) != 0 ) |
|
{ |
|
console.log( e ); |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if ( dataType == DATAH265 ) |
|
{ |
|
decCore.rCalc[ 0 ].dataType = DATAH265; |
|
if ( decCore.para.decode[ 0 ] != DATAH265 ) |
|
{ |
|
decCore.terminate_worker( 0 ); |
|
decCore.drawBlank( 0 ); |
|
decCore.para.decode[ 0 ] = DATAH265; |
|
decCore.init_worker( 0 ); |
|
} |
|
|
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
//console.log( "0x" + byte[24].toString(16) + byte[25].toString(16) + byte[26].toString(16) + byte[27].toString(16) + byte[28].toString(16) ); |
|
if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ 0 ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + 0 + "ch_id: " + ch_id ); |
|
decCore.iframeCnt[ 0 ] -= 1; |
|
if ( decCore.iframeCnt[ 0 ] > 0 ) |
|
return; |
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if(dataType == DATAJPEG) |
|
{ |
|
//console.log("dataType == DATAJPEG"); |
|
decCore.rCalc[ 0 ].dataType = DATAJPEG; |
|
if ( decCore.para.decode[ 0 ] != DATAJPEG ) |
|
{ |
|
//console.log("decCore.para.decode[ 0 ] != DATAJPEG"); |
|
decCore.terminate_worker( 0 ); |
|
decCore.drawBlank( 0 ); |
|
decCore.para.decode[ 0 ] = DATAJPEG; |
|
decCore.init_worker( 0 ); |
|
} |
|
|
|
//if ( isH26XData( byte, 24 ) ) |
|
{ |
|
//console.log( "0x" + byte[24].toString(16) + byte[25].toString(16) + byte[26].toString(16) + byte[27].toString(16) + byte[28].toString(16) ); |
|
|
|
|
|
if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if ( dataType == DATAG711U ) |
|
{ |
|
//console.log("decoded.length:"+decoded.length); |
|
for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) |
|
{ |
|
decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); |
|
//decCore.regServerCmdCb[ _registered_len ].func( { length : decoded.length, data: decoded } ); |
|
break; |
|
} |
|
} |
|
/*if ( decCore.decodeWorker( 0, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type, dataType) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
}*/ |
|
} |
|
} |
|
//else |
|
// console.log( byte ); |
|
} |
|
}; |
|
|
|
|
|
decCore.singleEvtMultiWorkerJSONContent = function ( event ) |
|
{ |
|
var actNum = event.lastEventId % decCore.para.worker_num; |
|
var obj = JSON.parse( event.data ); |
|
decCore.lastJsonTimeString = obj.time; |
|
if ( ( obj.h264 ) && ( ( typeof( obj.h264 ) != "undefined" ) ) ) |
|
{ |
|
var byte = parseHexString( obj.h264 );//need testing |
|
if ( decCore.isUniH264Data( byte ) ) |
|
decCore.decodeWorker( actNum , byte.length, byte ); |
|
} |
|
}; |
|
|
|
decCore.multi_dec_wr_one_ws_wr = function ( e ) |
|
{ |
|
if ( typeof e.data == "string" ) |
|
{ |
|
console.log("decCore.multi_dec_wr_one_ws_wr string"); |
|
if ( e.data == "wsonerror" ) |
|
{ |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
else if ( e.data.search( "wsservercmd?" ) != -1 )////from server |
|
{ |
|
var cmd = e.data.replace( "wsservercmd?", "" ); |
|
var cmdarray = cmd.split( "&" ); |
|
for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) |
|
{ |
|
var cmditem = cmdarray[ cmdcount ].split( "=" ); |
|
//now we can seach the register callback, if the name matched, put the value into the call back function |
|
for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); |
|
else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array |
|
{ |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem ); |
|
} |
|
} |
|
} |
|
} |
|
else if ( e.data.search( "wsserverinfo?" ) != -1 )//just information from server not command |
|
{ |
|
console.log( e.data ); |
|
if ( e.data.search( "wsserverinfo?playbackinfo=fps" ) != -1 ) |
|
{ |
|
_info = e.data.replace( "wsserverinfo?playbackinfo=fps", "" ); |
|
_info_array = _info.split( "&" ); |
|
for ( _i = 0; _i < _info_array.length; _i++ ) |
|
{ |
|
_info_item = _info_array[ _i ].split( "=" ); |
|
if ( _info_item[ 0 ] ) |
|
{ |
|
_info_item_des = _info_item[ 0 ].split( "_" ); |
|
_ch = parseInt( _info_item_des[ 1 ], 10 ); |
|
if ( typeof _ch == "number" ) |
|
{ |
|
if ( decCore.playback_info == null ) |
|
decCore.playback_info = []; |
|
|
|
if ( typeof decCore.playback_info[ _ch ] == "undefined" ) |
|
decCore.playback_info[ _ch ] = { v: 0, a: 0 }; |
|
|
|
if ( _info_item_des[ 2 ] == "v" ) |
|
decCore.playback_info[ _ch ].v = parseInt( _info_item[ 1 ], 10 ); |
|
if ( _info_item_des[ 2 ] == "a" ) |
|
decCore.playback_info[ _ch ].a = parseInt( _info_item[ 1 ], 10 ); |
|
} |
|
} |
|
|
|
} |
|
} |
|
else if ( e.data.search( "wsserverinfo?playbackinfo=state" ) != -1 ) |
|
{ |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
var byte = new Uint8Array( e.data ); |
|
|
|
if ( ( isHeaderPreamble( byte ) ) && ( byte.length > 24 ) ) |
|
{ |
|
var dataType = getHeaderDataType( byte ); |
|
var ch_id = getHeaderId( byte ); |
|
|
|
//var frame_timestamp = Date.now(); |
|
var dec_id = ch_id % decCore.para.worker_num; |
|
if ( decCore.byte_handle[ dec_id ] == false ) |
|
{ |
|
//console.log( "dec_id: " + dec_id ); |
|
return; |
|
} |
|
|
|
decCore.valid_byte_received[ dec_id ] = true; |
|
|
|
if ( decCore.buffering_activated ) |
|
{ |
|
_frame_t = getHeaderTime( byte ); |
|
if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, |
|
v_times: [], |
|
a_time: 0, |
|
v_pass: false, |
|
v_array : [], }; |
|
} |
|
|
|
if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].ch = ch_id |
|
decCore.buffering_ctrl[ dec_id ].v_times = []; |
|
decCore.buffering_ctrl[ dec_id ].v_array = []; |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
return; |
|
} |
|
else |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec |
|
( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse |
|
{ |
|
byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) |
|
decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; |
|
} |
|
} |
|
|
|
var frame_timestamp = Date.now(); |
|
var frame_type = FRAME_P; |
|
|
|
dataType = getHeaderDataType( byte ); |
|
ch_id = getHeaderId( byte ); |
|
|
|
dec_id = ch_id % decCore.para.worker_num; |
|
console.log( "ch_id:" + ch_id + " dec_id:" + dec_id ); |
|
decCore.lastJsonTime = getHeaderTime( byte ); |
|
decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); |
|
|
|
if ( dataType == DATAH264 ) |
|
{ |
|
console.log("dataType == DATAH264....1"); |
|
if ( decCore.para.decode[ dec_id ] != DATAH264 ) |
|
{ |
|
decCore.terminate_worker( dec_id ); |
|
decCore.para.decode[ dec_id ] = DATAH264; |
|
decCore.init_worker( dec_id ); |
|
} |
|
decCore.rCalc[ dec_id ].dataType = DATAH264; |
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
if ( byte[ 28 ] == 0x67 ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); |
|
decCore.iframeCnt[ dec_id ] -= 1; |
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
return; |
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) |
|
{ |
|
console.log( e ); |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
else |
|
console.log( "~~~" ); |
|
} |
|
else if ( dataType == DATAH265 ) |
|
{ |
|
console.log("dataType == DATAH265....1"); |
|
decCore.rCalc[ dec_id ].dataType = DATAH265; |
|
if ( decCore.para.decode[ dec_id ] != DATAH265 ) |
|
{ |
|
decCore.terminate_worker( dec_id ); |
|
decCore.drawBlank( dec_id ); |
|
decCore.para.decode[ dec_id ] = DATAH265; |
|
decCore.init_worker( dec_id ); |
|
} |
|
|
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); |
|
decCore.iframeCnt[ dec_id ] -= 1; |
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
return; |
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( ch_id % decCore.para.worker_num, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if ( dataType == DATAG711U ) |
|
{ |
|
console.log("dataType == DATAG711U....1"); |
|
for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) |
|
{ |
|
decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
//else |
|
// console.log( byte ); |
|
} |
|
} |
|
|
|
decCore.multiWorkerEvt = function( event ) |
|
{ |
|
var actNum = event.lastEventId % decCore.para.worker_num; |
|
var byte = parseHexString( event.data ); |
|
if ( decCore.isUniH264Data( byte ) ) |
|
{ |
|
if( decCore.iframeCnt[ actNum ] > 0 ) |
|
{ |
|
if( byte[ 4 ] == 0x67 ) |
|
{ |
|
decCore.iframeCnt[ actNum ] -= 1; |
|
decCore.decodeWorker( actNum , byte.length, byte ); |
|
} |
|
} |
|
else |
|
decCore.decodeWorker( actNum, byte.length, byte ); |
|
} |
|
}; |
|
|
|
decCore.multi_dec_wr_multi_ws_wr = function (e) { |
|
if ( typeof e.data == "string" ) |
|
{ |
|
if ( e.data == "wsonerror" ) |
|
{ |
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
else if ( e.data.search( "wsservercmd?" ) != -1 )////from server |
|
{ |
|
var cmd = e.data.replace( "wsservercmd?", "" ); |
|
var cmdarray = cmd.split( "&" ); |
|
for ( var cmdcount = 0; cmdcount < cmdarray.length; cmdcount++ ) |
|
{ |
|
var cmditem = cmdarray[ cmdcount ].split( "=" ); |
|
//now we can seach the register callback, if the name matched, put the value into the call back function |
|
for ( var registered_len = 0; registered_len < decCore.regServerCmdCb.length; registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ registered_len ].name == cmditem[ 0 ] ) |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem[ 1 ] ); |
|
else if ( cmditem[ 0 ].search( decCore.regServerCmdCb[ registered_len ].name ) != -1 )//not 100% match perhaps array |
|
{ |
|
decCore.regServerCmdCb[ registered_len ].func( cmditem ); |
|
} |
|
} |
|
} |
|
} |
|
else if ( e.data.search( "wsserverinfo?" ) != -1 )//just information from server not command |
|
{ |
|
console.log( e.data ); |
|
if ( e.data.search( "wsserverinfo?playbackinfo=fps" ) != -1 ) |
|
{ |
|
_info = e.data.replace( "wsserverinfo?playbackinfo=fps", "" ); |
|
_info_array = _info.split( "&" ); |
|
for ( _i = 0; _i < _info_array.length; _i++ ) |
|
{ |
|
_info_item = _info_array[ _i ].split( "=" ); |
|
if ( _info_item[ 0 ] ) |
|
{ |
|
_info_item_des = _info_item[ 0 ].split( "_" ); |
|
_ch = parseInt( _info_item_des[ 1 ], 10 ); |
|
if ( typeof _ch == "number" ) |
|
{ |
|
if ( decCore.playback_info == null ) |
|
decCore.playback_info = []; |
|
|
|
if ( typeof decCore.playback_info[ _ch ] == "undefined" ) |
|
decCore.playback_info[ _ch ] = { v: 0, a: 0 }; |
|
|
|
if ( _info_item_des[ 2 ] == "v" ) |
|
decCore.playback_info[ _ch ].v = parseInt( _info_item[ 1 ], 10 ); |
|
if ( _info_item_des[ 2 ] == "a" ) |
|
decCore.playback_info[ _ch ].a = parseInt( _info_item[ 1 ], 10 ); |
|
} |
|
} |
|
|
|
} |
|
} |
|
else if ( e.data.search( "wsserverinfo?playbackinfo=state" ) != -1 ) |
|
{ |
|
} |
|
} |
|
//console.log( e ); |
|
//console.log( e.srcElement ); |
|
} |
|
else |
|
{ |
|
var byte = new Uint8Array( e.data ); |
|
if ( ( isHeaderPreamble( byte ) )&&( byte.length > 24 ) ) |
|
{ |
|
var dataType = getHeaderDataType( byte ); |
|
var ch_id = getHeaderId( byte ); |
|
//var frame_type = FRAME_P; |
|
//var frame_timestamp = Date.now(); |
|
var dec_id = ch_id % decCore.para.worker_num; |
|
if ( decCore.byte_handle[ dec_id ] == false ) |
|
return; |
|
|
|
decCore.valid_byte_received[ dec_id ] = true; |
|
|
|
if ( decCore.buffering_activated ) |
|
{ |
|
_frame_t = getHeaderTime( byte ); |
|
if ( typeof decCore.buffering_ctrl[ dec_id ] == "undefined" ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ] = { ch: ch_id, |
|
v_times: [], |
|
a_time: 0, |
|
v_pass: false, |
|
v_array : [], }; |
|
} |
|
|
|
if ( ( dataType == DATAH264 ) || ( dataType == DATAH265 ) ) |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].ch != ch_id ) |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].ch = ch_id |
|
decCore.buffering_ctrl[ dec_id ].v_times = []; |
|
decCore.buffering_ctrl[ dec_id ].v_array = []; |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
return; |
|
} |
|
else |
|
{ |
|
decCore.buffering_ctrl[ dec_id ].v_times.push( _frame_t ); |
|
decCore.buffering_ctrl[ dec_id ].v_array.push( byte ); |
|
if ( ( ( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] /*+ 1*/ ) < decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) || //over 1sec |
|
( decCore.buffering_ctrl[ dec_id ].v_times[ 0 ] > decCore.buffering_ctrl[ dec_id ].v_times[ decCore.buffering_ctrl[ dec_id ].v_times.length - 1 ] ) )//reverse |
|
{ |
|
byte = decCore.buffering_ctrl[ dec_id ].v_array.shift(); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if ( decCore.buffering_ctrl[ dec_id ].a_time != _frame_t ) |
|
decCore.buffering_ctrl[ dec_id ].a_time = _frame_t; |
|
} |
|
} |
|
|
|
var frame_timestamp = Date.now(); |
|
var frame_type = FRAME_P; |
|
|
|
decCore.lastJsonTime = getHeaderTime( byte ); |
|
decCore.lastJsonTimeString = getHeaderTimeString( decCore.lastJsonTime ); |
|
|
|
dataType = getHeaderDataType( byte ); |
|
ch_id = getHeaderId( byte ); |
|
dec_id = ch_id % decCore.para.worker_num; |
|
//console.log( "ch_id:" + ch_id + " dec_id:" + dec_id ); |
|
if ( dataType == DATAH264 ) |
|
{ |
|
console.log("dataType == DATAH264.....2"); |
|
if ( decCore.para.decode[ dec_id ] != DATAH264 ) |
|
{ |
|
decCore.terminate_worker( dec_id ); |
|
decCore.para.decode[ dec_id ] = DATAH264; |
|
decCore.init_worker( dec_id ); |
|
} |
|
|
|
decCore.rCalc[ dec_id ].dataType = DATAH264; |
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
if ( byte[ 28 ] == 0x67 ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); |
|
decCore.iframeCnt[ dec_id ] -= 1; |
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
return; |
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if ( dataType == DATAH265 ) |
|
{ |
|
decCore.rCalc[ dec_id ].dataType = DATAH265; |
|
if ( decCore.para.decode[ dec_id ] != DATAH265 ) |
|
{ |
|
decCore.terminate_worker( dec_id ); |
|
decCore.drawBlank( dec_id ); |
|
decCore.para.decode[ dec_id ] = DATAH265; |
|
decCore.init_worker( dec_id ); |
|
} |
|
|
|
if ( isH26XData( byte, 24 ) ) |
|
{ |
|
if ( ( H265_NALU( byte[ 24 + 4 ] ) == 32 ) || ( H265_NALU( byte[ 24 + 4 ] ) == 33 ) ) |
|
frame_type = FRAME_I; |
|
|
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
{ |
|
if ( frame_type == FRAME_I ) |
|
{ |
|
//console.log( "dec_id: " + dec_id + "ch_id: " + ch_id ); |
|
decCore.iframeCnt[ dec_id ] -= 1; |
|
if ( decCore.iframeCnt[ dec_id ] > 0 ) |
|
return; |
|
} |
|
else |
|
return; |
|
} |
|
|
|
if ( decCore.decodeWorker( dec_id, byte.length - 24 , byte.slice( 24 ), frame_timestamp, frame_type ) != 0 ) |
|
{ |
|
console.log( e ); |
|
|
|
if (( e.srcElement != null ) && ( typeof e.srcElement != "undefined" )) |
|
e.srcElement.onerror(); |
|
else if (( e.target != null ) && ( typeof e.target != "undefined" )) |
|
e.target.onerror(); |
|
} |
|
} |
|
} |
|
else if ( dataType == DATAG711U )// search is there register audio cb function |
|
{ |
|
console.log("dataType == DATAG711U.....2"); |
|
for ( _registered_len = 0; _registered_len < decCore.regServerCmdCb.length; _registered_len++ ) |
|
{ |
|
if ( decCore.regServerCmdCb[ _registered_len ].name == ( "audio_" + getHeaderChannel( byte ) ) ) |
|
{ |
|
decCore.regServerCmdCb[ _registered_len ].func( { length : byte.length - 24, data: byte.slice( 24 ) } ); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
//else |
|
// console.log( "Preamble Error!" ); |
|
} |
|
}; |
|
|
|
decCore.singleWorkerEvt = function( event ) |
|
{ |
|
var byte = parseHexString( event.data ) |
|
if ( decCore.isUniH264Data( byte ) ) |
|
{ |
|
if( decCore.iframeCnt[ 0 ] > 0 ) |
|
{ |
|
if( byte[ 4 ] == 0x67 ) |
|
{ |
|
decCore.iframeCnt[ 0 ] -= 1; |
|
decCore.decodeWorker( 0 , byte.length, byte ); |
|
} |
|
} |
|
else |
|
decCore.decodeWorker( 0 , byte.length, byte ); |
|
} |
|
}; |
|
|
|
decCore.get_vc_element = function( workerNum ) |
|
{ |
|
return decCore.yuvCanvas[ workerNum ].canvasElement; |
|
}; |
|
|
|
decCore.set_vc_element_size = function( workerNum, setting_width, setting_height ) |
|
{ |
|
decCore.yuvCanvas[ workerNum ].canvasElement.style.width = ( setting_width + "px" ); |
|
decCore.yuvCanvas[ workerNum ].canvasElement.style.height = ( setting_height + "px" ); |
|
}; |
|
|
|
decCore.terminateYUV = function() |
|
{ |
|
for ( var i = 0; i < decCore.para.worker_num; i++ ) |
|
decCore.yuvCanvas[ i ] = null; |
|
}; |
|
|
|
decCore.setDropLatencyDecoded = function( on_off ) |
|
{ |
|
decCore.dropLatencyDecoded = on_off; |
|
if ( decCore.dropLatencyDecoded == true ) |
|
{ |
|
for ( _i = 0; _i < decCore.rCalc.length; _i++ ) |
|
decCore.rCalc[ _i ] = new _recvCalc; |
|
for ( _i = 0; _i < decCore.worker.length; _i++ ) |
|
{ |
|
if ( decCore.iframeCnt[ _i ] <= 0 ) |
|
decCore.iframeCnt[ _i ] = 1; |
|
} |
|
} |
|
}; |
|
|
|
for ( var i = 0; i < para.worker_num; i++ ) |
|
decCore.init_worker( i ); |
|
}
|
|
|