软编码Flv 到Mp4 容器(外传一)avcc box
avcc boxavcc是AVCDecoderConfigurationRecordAVC decoder configuration record定义aligned(8) class AVCDecoderConfigurationRecord {unsigned int(8) configurationVersion = 1;unsigned int(8) AVCProfileIndica
·
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);
更多推荐
已为社区贡献1条内容
所有评论(0)