软编码Flv 到Mp4 容器(外传一)avcc box

来源:互联网 发布:网络医生妇科 编辑:程序博客网 时间:2024/05/29 09:30

avcc box

avcc是AVCDecoderConfigurationRecord

AVC decoder configuration record

定义

aligned(8) class AVCDecoderConfigurationRecord { unsigned int(8) configurationVersion = 1; unsigned int(8) AVCProfileIndication; unsigned int(8) profile_compatibility; unsigned int(8) AVCLevelIndication;bit(6) reserved = ‘111111’b;unsigned int(2) lengthSizeMinusOne;bit(3) reserved = ‘111’b;unsigned int(5) numOfSequenceParameterSets;for (i=0; i< numOfSequenceParameterSets; i++) {  unsigned int(16) sequenceParameterSetLength ;  bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit; }unsigned int(8) numOfPictureParameterSets;for (i=0; i< numOfPictureParameterSets; i++) {  unsigned int(16) pictureParameterSetLength;  bit(8*pictureParameterSetLength) pictureParameterSetNALUnit; }}
> lengthSizeMinusOneindicates the length in bytes of the NALUnitLength field in an AVC video sample or AVC parameter set sample of the associated stream minus one. For example, a size of one byte is indicated with a value of 0. The value of this field shall be one of 0, 1, or 3 corresponding to a length encoded with 1, 2, or 4 bytes, respectively.> numOfSequenceParameterSetsindicates the number of SPSs that are used as the initial set of SPSs for decoding the AVC elementary stream.> sequenceParameterSetLength indicates the length in bytes of the SPS NAL unit as defined in ISO/IEC 14496-10.> sequenceParameterSetNALUnit contains a SPS NAL unit, as specified in ISO/IEC 14496-10. SPSs shall occur in order of ascending parameter set identifier with gaps being allowed.> numOfPictureParameterSets indicates the number of picture parameter sets (PPSs) that are used as the initial set of PPSs for decoding the AVC elementary stream.> pictureParameterSetLength indicates the length in bytes of the PPS NAL unit as defined in ISO/IEC 14496-10.> pictureParameterSetNALUnit contains a PPS NAL unit, as specified in ISO/IEC 14496-10. PPSs shall occur in order of ascending parameter set identifier with gaps being allowed.

是第一个video tag的body

v= (video tag).body//略过前5个字节let offset=5;let version = v.getUint8(offset+0);  // configurationVersionlet avcProfile = v.getUint8(offset+1);  // avcProfileIndicationlet profileCompatibility = v.getUint8(offset+2);  // profile_compatibilitylet avcLevel = v.getUint8(offset+3);  // AVCLevelIndicationthis._naluLengthSize = (v.getUint8(offset+4) & 3) + 1;  // lengthSizeMinusOne   上一个avc 长度let spsCount = v.getUint8(offset+5) & 31;  // numOfSequenceParameterSetslet offset = offset+6;for (let i = 0; i < spsCount; i++) {            let len = v.getUint16(offset, !le);  // sequenceParameterSetLength            offset += 2;            if (len === 0) {                continue;            }            // Notice: Nalu without startcode header (00 00 00 01)            let sps = new Uint8Array(v.buffer, offset, len);            offset += len;            let config = SPSParser.parseSPS(sps);            meta.codecWidth = config.codec_size.width;            meta.codecHeight = config.codec_size.height;            meta.presentWidth = config.present_size.width;            meta.presentHeight = config.present_size.height;            meta.profile = config.profile_string;            meta.level = config.level_string;            meta.bitDepth = config.bit_depth;            meta.chromaFormat = config.chroma_format;            meta.sarRatio = config.sar_ratio;            meta.frameRate = config.frame_rate;            if (config.frame_rate.fixed === false ||                config.frame_rate.fps_num === 0 ||                config.frame_rate.fps_den === 0) {                meta.frameRate = this._referenceFrameRate;            }            let fps_den = meta.frameRate.fps_den;            let fps_num = meta.frameRate.fps_num;            meta.refSampleDuration = Math.floor(meta.timescale * (fps_den / fps_num));            let codecArray = sps.subarray(1, 4);            let codecString = 'avc1.';            for (let j = 0; j < 3; j++) {                let h = codecArray[j].toString(16);                if (h.length < 2) {                    h = '0' + h;                }                codecString += h;            }            meta.codec = codecString;            let mi = this._mediaInfo;            mi.width = meta.codecWidth;            mi.height = meta.codecHeight;            mi.fps = meta.frameRate.fps;            mi.profile = meta.profile;            mi.level = meta.level;            mi.chromaFormat = config.chroma_format_string;            mi.sarNum = meta.sarRatio.width;            mi.sarDen = meta.sarRatio.height;            mi.videoCodec = codecString;            if (mi.hasAudio) {                if (mi.audioCodec != null) {                    mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + ',' + mi.audioCodec + '"';                }            } else {                mi.mimeType = 'video/x-flv; codecs="' + mi.videoCodec + '"';            }            if (mi.isComplete()) {                this._onMediaInfo(mi);            }        }        let ppsCount = v.getUint8(offset);  // numOfPictureParameterSets        if (ppsCount === 0 || ppsCount > 1) {            this._onError(DemuxErrors.FORMAT_ERROR, `Flv: Invalid H264 PPS count: ${ppsCount}`);            return;        }        offset++;        for (let i = 0; i < ppsCount; i++) {            let len = v.getUint16(offset, !le);  // pictureParameterSetLength            offset += 2;            if (len === 0) {                continue;            }            // pps is useless for extracting video information            offset += len;        }        meta.avcc = new Uint8Array(dataSize);        meta.avcc.set(new Uint8Array(arrayBuffer, dataOffset, dataSize), 0);

阅读全文
0 0
原创粉丝点击