123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- /*********************************************************
- * LICENSE: LICENSE-Free_CN.MD
- *
- * Author: Numberwolf - ChangYanlong
- * QQ: 531365872
- * QQ Group:925466059
- * Wechat: numberwolf11
- * Discord: numberwolf#8694
- * E-Mail: porschegt23@foxmail.com
- * Github: https://github.com/numberwolf/h265web.js
- *
- * 作者: 小老虎(Numberwolf)(常炎隆)
- * QQ: 531365872
- * QQ群: 531365872
- * 微信: numberwolf11
- * Discord: numberwolf#8694
- * 邮箱: porschegt23@foxmail.com
- * 博客: https://www.jianshu.com/u/9c09c1e00fd1
- * Github: https://github.com/numberwolf/h265web.js
- *
- **********************************************************/
- /**
- * codecImp Obj
- * Video Raw 265 264 Parser
- */
- const AfterGetNalThenMvLen = 3;
- export default class RawParserModule {
- constructor() {
- this.frameList = [];
- this.stream = null;
- }
- /*
- *****************************************************
- * *
- * *
- * HEVC Frames *
- * *
- * *
- *****************************************************
- */
- pushFrameRet(streamPushInput) {
- if (!streamPushInput || streamPushInput == undefined || streamPushInput == null) {
- return false;
- }
- if (!this.frameList || this.frameList == undefined || this.frameList == null) {
- this.frameList = [];
- this.frameList.push(streamPushInput);
-
- } else {
- this.frameList.push(streamPushInput);
- }
- return true;
- }
- nextFrame() {
- if (!this.frameList && this.frameList == undefined || this.frameList == null && this.frameList.length < 1) {
- return null;
- }
- return this.frameList.shift();
- }
- clearFrameRet() {
- this.frameList = null;
- }
- /*
- *****************************************************
- * *
- * *
- * HEVC stream *
- * *
- * *
- *****************************************************
- */
- setStreamRet(streamBufInput) {
- this.stream = streamBufInput;
- }
- getStreamRet() {
- return this.stream;
- }
- /**
- * push stream nalu, for live, not vod
- * @param Uint8Array
- * @return bool
- */
- appendStreamRet(input) {
- if (!input || input === undefined || input == null) {
- return false;
- }
- if (!this.stream || this.stream === undefined || this.stream == null) {
- this.stream = input;
- return true;
- }
- let lenOld = this.stream.length;
- let lenPush = input.length;
- let mergeStream = new Uint8Array(lenOld + lenPush);
- mergeStream.set(this.stream, 0);
- mergeStream.set(input, lenOld);
- this.stream = mergeStream;
- // let retList = this.nextNaluList(9000);
- // if (retList !== false && retList.length > 0) {
- // this.frameList.push(...retList);
- // }
- for (let i = 0; i < 9999; i++) {
- let nalBuf = this.nextNalu();
- if (nalBuf !== false && nalBuf !== null && nalBuf !== undefined) {
- this.frameList.push(nalBuf);
- } else {
- break;
- }
- }
- return true;
- }
- /**
- * sub nalu stream, and get Nalu unit
- */
- subBuf(startOpen, endOpen) { // sub block [m,n]
- // nal
- let returnBuf = new Uint8Array(
- this.stream.subarray(startOpen, endOpen + 1)
- );
- // streamBuf sub
- this.stream = new Uint8Array(
- this.stream.subarray(endOpen + 1)
- );
- return returnBuf;
- }
- /**
- * @param onceGetNalCount: once use get nal count, defult 1
- * @return uint8array OR false
- */
- nextNalu(onceGetNalCount=1) {
- // check params
- if (this.stream == null || this.stream.length <= 4) {
- return false;
- }
- // start nal pos
- let startTag = -1;
- // return nalBuf
- let returnNalBuf = null;
- for (let i = 0;i < this.stream.length; i++) {
- if (i + 5 >= this.stream.length) {
- return false;
- // if (startTag == -1) {
- // return false;
- // } else {
- // // 如果结尾不到判断的字节位置 就直接全量输出最后一个nal
- // returnNalBuf = this.subBuf(startTag, this.stream.length-1);
- // return returnNalBuf;
- // }
- }
- // find nal
- if (
- ( // 0x00 00 01
- this.stream[i] == 0
- && this.stream[i+1] == 0
- && this.stream[i+2] == 1
- ) ||
- ( // 0x00 00 00 01
- this.stream[i] == 0
- && this.stream[i+1] == 0
- && this.stream[i+2] == 0
- && this.stream[i+3] == 1
- )
- ) {
- // console.log(
- // "enter find nal , now startTag:" + startTag
- // + ", now pos:" + i
- // );
- let nowPos = i;
- i += AfterGetNalThenMvLen; // 移出去
- // begin pos
- if (startTag == -1) {
- startTag = nowPos;
- } else {
- if (onceGetNalCount <= 1) {
- // startCode - End
- // [startTag,nowPos)
- // console.log("[===>] last code hex is :" + this.stream[nowPos-1].toString(16))
- returnNalBuf = this.subBuf(startTag,nowPos-1);
- return returnNalBuf;
- } else {
- onceGetNalCount -= 1;
- }
- }
- }
- } // end for
- return false;
- }
- nextNalu2(onceGetNalCount=1) {
- // check params
- if (this.stream == null || this.stream.length <= 4) {
- return false;
- }
- // start nal pos
- let startTag = -1;
- // return nalBuf
- let returnNalBuf = null;
- for (let i = 0;i < this.stream.length; i++) {
- if (i + 5 >= this.stream.length) {
- if (startTag == -1) {
- return false;
- } else {
- // 如果结尾不到判断的字节位置 就直接全量输出最后一个nal
- returnNalBuf = this.subBuf(startTag,this.stream.length-1);
- return returnNalBuf;
- }
- }
- // find nal
- let is3BitHeader = this.stream.slice(i, i+3).join(' ') == '0 0 1';
- let is4BitHeader = this.stream.slice(i, i+4).join(' ') == '0 0 0 1';
- if (
- is3BitHeader ||
- is4BitHeader
- ) {
- let nowPos = i;
- i += AfterGetNalThenMvLen; // 移出去
- // begin pos
- if (startTag == -1) {
- startTag = nowPos;
- } else {
- if (onceGetNalCount <= 1) {
- // startCode - End
- // [startTag,nowPos)
- // console.log("[===>] last code hex is :" + this.stream[nowPos-1].toString(16))
- returnNalBuf = this.subBuf(startTag, nowPos-1);
- return returnNalBuf;
- } else {
- onceGetNalCount -= 1;
- }
- }
- }
- } // end for
- return false;
- }
- /**
- * @brief sub nalu stream, and get Nalu unit
- * to parse:
- * typedef struct {
- * uint32_t width;
- * uint32_t height;
- * uint8_t *dataY;
- * uint8_t *dataChromaB;
- * uint8_t *dataChromaR;
- * } ImageData;
- * @params struct_ptr: Module.cwrap('getFrame', 'number', [])
- * @return Dict
- */
- parseYUVFrameStruct(struct_ptr = null) { // sub block [m,n]
- if (struct_ptr == null || !struct_ptr || struct_ptr == undefined) {
- return null;
- }
- let width = Module.HEAPU32[struct_ptr / 4];
- let height = Module.HEAPU32[struct_ptr / 4 + 1];
- // let imgBufferPtr = Module.HEAPU32[ptr / 4 + 2];
- // let imageBuffer = Module.HEAPU8.subarray(imgBufferPtr, imgBufferPtr + width * height * 3);
- // console.log("width:",width," height:",height);
- let sizeWH = width * height;
- // let imgBufferYPtr = Module.HEAPU32[ptr / 4 + 2];
- // let imageBufferY = Module.HEAPU8.subarray(imgBufferYPtr, imgBufferYPtr + sizeWH);
- // let imgBufferBPtr = Module.HEAPU32[ptr/4+ 2 + sizeWH/4 + 1];
- // let imageBufferB = Module.HEAPU8.subarray(
- // imgBufferBPtr,
- // imgBufferBPtr + sizeWH/4
- // );
- // console.log(imageBufferB);
- // let imgBufferRPtr = Module.HEAPU32[imgBufferBPtr + sizeWH/16 + 1];
- // let imageBufferR = Module.HEAPU8.subarray(
- // imgBufferRPtr,
- // imgBufferRPtr + sizeWH/4
- // );
- let imgBufferPtr = Module.HEAPU32[struct_ptr / 4 + 1 + 1];
- let imageBufferY = Module.HEAPU8.subarray(imgBufferPtr, imgBufferPtr + sizeWH);
- let imageBufferB = Module.HEAPU8.subarray(
- imgBufferPtr + sizeWH + 8,
- imgBufferPtr + sizeWH + 8 + sizeWH/4
- );
- let imageBufferR = Module.HEAPU8.subarray(
- imgBufferPtr + sizeWH + 8 + sizeWH/4 + 8,
- imgBufferPtr + sizeWH + 8 + sizeWH/2 + 8
- );
- return {
- width : width,
- height : height,
- sizeWH : sizeWH,
- imageBufferY : imageBufferY,
- imageBufferB : imageBufferB,
- imageBufferR : imageBufferR
- };
- }
- }
|