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

原创 2017年05月23日 18:06:11

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; 
}
}


> lengthSizeMinusOne

indicates 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.

> numOfSequenceParameterSets

indicates 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);  // configurationVersion
let avcProfile = v.getUint8(offset+1);  // avcProfileIndication
let profileCompatibility = v.getUint8(offset+2);  // profile_compatibility
let avcLevel = v.getUint8(offset+3);  // AVCLevelIndication

this._naluLengthSize = (v.getUint8(offset+4) & 3) + 1;  // lengthSizeMinusOne   上一个avc 长度

let spsCount = v.getUint8(offset+5) & 31;  // numOfSequenceParameterSets

let 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);

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

软编码Flv 到Mp4 容器(四) fmp4 总览和基础讲解

https://github.com/332065255/flv2fmp4代码库首先约定几个定义 mp4容器,是由box组成 box分为Container box 和full boxContain...

MP4文件中如何寻找一个sample--MP4文件简单解析

晚上搜索MP4格式的文章。都是从上到下,从外到里,一层一层开拔各种的box,等到了真正感兴趣的boxer的时候,通常观看者已经累的老眼昏花,那么多的boxer。那么多的名字。怎么记得住呢? 我将从...
  • ddr77
  • ddr77
  • 2016年09月09日 11:37
  • 990

软编码Flv 到Mp4 容器(十) fmp4 mvex box 讲解

https://github.com/332065255/flv2fmp4代码库 - ftyp - moov - mvhd - trak - tkhd ...

软编码Flv 到Mp4 容器(八) fmp4 mdia>stbl>stsd box 讲解

https://github.com/332065255/flv2fmp4代码库先占坑(未完待续)

软编码Flv 到Mp4 容器(九) fmp4 stts stsc stsz stco box 讲解

https://github.com/332065255/flv2fmp4代码库先占坑(未完待续)

软编码Flv 到Mp4 容器(六) fmp4 moov>trak>tkhd box 和 moov>trak>mdia>mdhd box讲解

https://github.com/332065255/flv2fmp4代码库先占坑(未完待续)

软编码Flv 到Mp4 容器(七) fmp4 mdia>hdlr box 和 mdia>minf> smhd 和dinf box讲解

https://github.com/332065255/flv2fmp4代码库先占坑(未完待续)

软编码Flv 到Mp4 容器(一)

这是一篇系列文章,用伪代码来一步步讲解flv 软编码到mp4本质上这是一篇对flv.js的解释,解释flv如何转换成mp4的现在网上关于mp4的资料不算少,但是从伪代码层级讲述一个容器到另一个容器的几...

软编码Flv 到Mp4 容器(二) flv tag拆解

https://github.com/332065255/flv2fmp4代码库接上篇文章,这章主要是对flv二进制数据进行tag拆解首先接上章的入口类import flvparse from './...

软编码Flv 到Mp4 容器(三) flv metadata tag解析

https://github.com/332065255/flv2fmp4代码库(未完待续,作者在码代码)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:软编码Flv 到Mp4 容器(外传一)avcc box
举报原因:
原因补充:

(最多只允许输入30个字)