音频格式之AAC:(2)AAC封装格式ADIF,ADTS,LATM,extradata及AAC ES存储格式

news2024/11/16 9:34:06

系列文章目录

音频格式的介绍文章系列:
音频编解码格式介绍(1) ADPCM:adpcm编解码原理及其代码实现
音频编解码格式介绍(2) MP3 :音频格式之MP3:(1)MP3封装格式简介
音频编解码格式介绍(2) MP3 :音频格式之MP3:(2)MP3编解码原理详解
音频编解码格式介绍(3) AAC :音频格式之AAC:(1)AAC简介
音频编解码格式介绍(3) AAC :音频格式之AAC:(2)AAC封装格式ADIF,ADTS,LATM,extradata及AAC ES存储格式
音频编解码格式介绍(3) AAC :音频格式之AAC:(3)AAC编解码原理详解


文章目录

  • 系列文章目录
  • 前言
  • 1、ADIF
    • 1.1 ADIF文件存储格式
    • 1.2 ADTS adif_header 帧头各字段含义
  • 2、ADTS
    • 2.1 adts_frame
    • 2.2 adts_fixed_header
    • 2.3 adts_variable_header
    • 2.4 Error detection
  • 3、LATM
    • 3.1 LATM文件存储格式
    • 3.2 latm _header 帧头各字段含义
    • 3.3 CMMB中的LATM
  • 4、extradata
    • 4.1 extradata存储格式
  • 5、AAC ES(raw data)
    • 5.1 AAC ES存储格式如下:
    • 5.2 element
    • 5.3 elementChan
  • 参考资料


前言

本文主要1-3部分介绍AAC封装格式ADIF,ADTS和LATM,同时因为从mp4等封装容器有extradata模式,故也第4部分介绍extradata模式。最后第5部分介绍AAC压缩数据存储方式。
说明如下:
1:本文主要介绍AAC封装格式,一个只有aac格式的编码的文件可能使用这三种后缀名:aac、m4a、mp4.
2:其中m4a后缀一般只有apple使用,只含有aac音频格式,没有视频。其实就是mp4封装格式,
对于m4a和mp4后缀属于mp4封装,不在这里介绍,后续会单独开篇介绍封装格式之mp4.
3:其中AAC格式包括ADIF,ADTS和LATM.
需要说明的是ADIF,ADTS和LATM只是AAC的三种封装方式,即只是封装方式不同,里面的编码数据都是和extradata模式一样的。
区别在于:
1:ADIF:只有一个头,其余后面都跟着raw data,文件存储体积小,智能从开始处一帧一帧解码,无法跳播,无法从中间位置解码。
2:ADTS:每帧都有7个字节的头,方便跳播,从任何位置都可以直接进行解码。
3:LATM:LATM格式具有很大的灵活性,每帧的音频配置单元既可以带内传输,又可以带外传输。正因为如此,LATM不仅适用于流传输还可以用于RTP传输,特别时CMMB广播默认码流格式为LATM。
4:extradata:这种模式一般是mp4,flv等封装格式中。extradata在header里面,解码时先传输extradata信息,然后开始传输raw data。每个文件只有一个extradata。其余全部时AAC ES。

主要参考资料为:ISO/IEC 13818-7和ISO/IEC 14496-3


1、ADIF

ADIF,Audio Data Interchange Format 音频数据交换格式,该格式一般应用在将音频通过写文件方式存储在磁盘里的场景,不能进行随机访问,不允许在文件中间开始进行解码;只能从文件头开始解码,无法跳播。

1.1 ADIF文件存储格式

ADIF文件存储格式如下:

adif_headerbyte_alignmentraw_data_stream

其中adif_header和raw_data_stream如下表:
请添加图片描述

1.2 ADTS adif_header 帧头各字段含义

请添加图片描述

说明如下:
1:byte_alignment 为了保持字节对齐用。
2:可以看到adif只有一个header,里面没有关于每帧信息,因为每帧不是固定大小,故只能按照顺序进行解码,也无法跳播或快进快退。除非自己解码遍历整个文件建立每帧位置表。

2、ADTS

ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。这种格式可以用于广播电视。

简言之。ADIF只有一个文件头,ADTS每个包前面有一个文件头。

最常见的ADTS文件存储格式如下:
请添加图片描述
1:aac的adts封装格式类似mp3封装格式,一帧一帧存储,每帧都有同步头,两帧直接允许有冗余数据
2:adts header为7个字节(固定(每帧都一样)header 28bit+变化(每帧之间可能不一样)header28bit)+ 2(crc,可选,一般adts没有crc校验)

2.1 adts_frame

详细的adts封装如下:
请添加图片描述

2.2 adts_fixed_header

其中adts_fixed_header结构如下:
请添加图片描述
ADTS fixed_header 帧头各字段含义

字段长度 bits说明解释
Syncword12all bits must be 1总是0xFFF,代表一个ADTS帧的开始,作为分界符,用于同步每帧起始位置
ID10 for MPEG-4, 1 for MPEG-2
Layer2always 0
Protection Absent1set to 1 if there is no CRC and 0 if there is CRC
Profile2the MPEG-4 Audio Object Type minus 1代表使用哪个级别和规范的 AAC,其中 01 代表 Low Complexity(LC),其中 profile 等于 Audio Object Type 的值减1
Sampling Frequency Index4MPEG-4 Sampling Frequency Index (15 is forbidden)采样率下标,由于 AAC 的采样率范围是 8KHz-96KHz,所以具体用那个,由该字段决定
Private Bit1set to 0 when encoding, ignore when decoding
Channel Configuration3MPEG-4 Channel Configuration (in the case of 0, the channel configuration is sent via an inband PCE)通道配置即声道数,一般 2 表示立体声双声道
Originality copy1set to 0 when encoding, ignore when decoding
Home1set to 0 when encoding, ignore when decoding

profile定义如下:

profile ObjectTypeMPEG-2 profile(ID==1)MPEG-4 object type(ID==0)
0Main profileAAC Main
1Low Complexity profile(LC)AAC LC
2Scalable Sampling Rate profile(SSR)AAC SSR
3(reserved)AAC LTP

profile在 MPEG-4 Audio Object Type(profile_ObjectType+1)参见14496-3的1.5.2.1如下图:
请添加图片描述

2.3 adts_variable_header

adts_variable_header结构如下:

请添加图片描述
ADTS variable_header 帧头各字段含义

字段长度 bits说明解释
Copyrighted identification bit1set to 0 when encoding, ignore when decoding
Copyrighted identification Start1set to 0 when encoding, ignore when decoding
Aac Frame Length13this value must include 7 or 9 bytes of header length FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)一个 ADTS 帧的长度包括 ADTS 头和 AAC 原始流
ADTS Buffer Fullness11buffer fullness0x7FF 表示码率可变的码流,0x000 表示固定码率的码流
Number of AAC Frames2number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frameADTS 帧中有 number_of_raw_data_blocks_in_frame + 1 个 AAC 原始帧;则 number_of_raw_data_blocks_in_frame == 0 表示 ADTS 帧中有一个 AAC 数据块;(一个 AAC 原始帧包含一段时间内 1024 个采样及相关数据)

2.4 Error detection

Error detection如下:
请添加图片描述

3、LATM

LATM 的全称为“Low-overhead MPEG-4 Audio TransportMultiplex”(低开销音频传输复用),是MPEG-4 AAC制定的一种高效率的码流传输方式,MPEG-2 TS 流也采用LATM作为AAC 音频码流的封装格式之 一。

3.1 LATM文件存储格式

文件存储格式如下:

latm_frame1latm_frame2

每帧latm_frame存储格式如下:

latm_headerbyte_alignmentraw_data_stream

latm_header格式如下:
请添加图片描述

3.2 latm _header 帧头各字段含义

字段长度 bits说明解释
syncword11always:0x2b7同步头,必须是0x2b7
audioMuxLengthBytes13audio mux length帧长,不包括前面(11+13)bit

AudioMuxElement结构如下:
请添加图片描述
StreamMuxConfig,PayloadLengthInfo,PayloadMux参见ISO/IEC 14496-3。

LATM格式也以帧为单位,主要由AudioSpecificConfig(音频特定配置单元)与音频负载组成。AudioSpecificConfig 描述了一个LATM 帧的信息,音频负载主要由PayloadLengthInfo(负载长度信息)和PayloadMux(负载净荷)组成。

AudioSpecificConfig 信息可以是带内传,也可以是带外传。所谓带内传,就是指每一个LATM 帧,都含有一个AudioSpecificConfig 信息;而带外传,则每一个LATM帧都不含有AudioSpecificConfig 信息,而通过其他方式把AudioSpecificConfig信息发送到解码端,由于AudioSpecificConfig 信息一般是不变的,所以只需发送一次即可。由此可见,
AudioSpecificConfig 信息采用带内传输可适应音频编码信息不断变化的情况,而采用带外传输,可以节省音频传输码率。带内或带外传,由muxconfigPresent 标志位决定。例如流媒体应用中,muxconfigPresent 可设置为0,这样LATM帧中将不含有AudioSpecificConfig 信息,LATM帧通过RTP包发送出去,AudioSpecificConfig 可通过SDP文件一次性传送到解码端。

AudioSpecificConfig 主要参数

参数含义
numSubFrames子帧的数目
numProgram复用的节目数
numLayer复用的层数
frameLengthType负载的帧长度类型,包括固定长度与可变长度
audioObjectType音频对象类型
samplingFrequency采样率
channelConfiguration声道配置

音频负载由若干子帧组成,每个子帧由PayloadLengthInfo和PayloadMux组成,与ADTS帧净荷一样,音频负载主要包含原始帧数据。

AAC打包成TS流通常有两种方式,分别是先打包成ADTS或LATM。ADTS的每一帧都有个帧头,在
每个帧头信息都一样的状况下,会有很大的冗余。LATM格式具有很大的灵活性,每帧的音频配置单元既可以带内传输,又可以带外传输。正因为如此,LATM不仅适用于流传输还可以用于RTP传输,
RTP传输时,若音频数据配置信息是保持不变,可以先通过SDP会话先传输StreamMuxConfig(AudioSpecificConfig)信息,由于LATM流由一个包含了一个或多个音频帧的audioMuxElements序列组成。一个完整或部分完整的audioMuxElement可直接映射到一个RTP负载上。

需要说明在开始解码的时候,需要先找到AudioSpecificConfig,才能获取解码信息,才能开始解码。AudioSpecificConfig并不是每帧都含有的

3.3 CMMB中的LATM

当CMMB中音频压缩标准为AAC时,默认采用LATM封装。StreamMuxConfig采用带外传输。
StreamMuxConifg中的若干默认参数如下:audioMuxVersion:0标志流语法版本号为0,
allStreamsSameTimeFraming标志复用到PayLoadMux()中的所有负载共享一个共同的时基音频子帧.

audioObjectType:2 AAC-LC

freameLengthType:0 帧长度是可变的

latmBufferFullness:0xFF 码率可变的码流

4、extradata

这种模式一般是mp4,flv等封装格式中。extradata在header里面,解码时先传输extradata信息,然后开始传输raw data。

4.1 extradata存储格式

extradata存储格式如下:

object_typesample_ratechan_config
5(+6)bits4(+24)bits4bits

具体查看ffmpeg的decode_audio_specific_config函数:

/**
 * Decode audio specific configuration; reference: table 1.13.
 *
 * @param   ac          pointer to AACContext, may be null
 * @param   avctx       pointer to AVCCodecContext, used for logging
 * @param   m4ac        pointer to MPEG4AudioConfig, used for parsing
 * @param   gb          buffer holding an audio specific config
 * @param   get_bit_alignment relative alignment for byte align operations
 * @param   sync_extension look for an appended sync extension
 *
 * @return  Returns error status or number of consumed bits. <0 - error
 */
static int decode_audio_specific_config_gb(AACContext *ac,
                                           AVCodecContext *avctx,
                                           MPEG4AudioConfig *m4ac,
                                           GetBitContext *gb,
                                           int get_bit_alignment,
                                           int sync_extension)
{
    int i, ret;
    GetBitContext gbc = *gb;
    MPEG4AudioConfig m4ac_bak = *m4ac;

    if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension, avctx)) < 0) {
        *m4ac = m4ac_bak;
        return AVERROR_INVALIDDATA;
    }

    if (m4ac->sampling_index > 12) {
        av_log(avctx, AV_LOG_ERROR,
               "invalid sampling rate index %d\n",
               m4ac->sampling_index);
        *m4ac = m4ac_bak;
        return AVERROR_INVALIDDATA;
    }
    if (m4ac->object_type == AOT_ER_AAC_LD &&
        (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) {
        av_log(avctx, AV_LOG_ERROR,
               "invalid low delay sampling rate index %d\n",
               m4ac->sampling_index);
        *m4ac = m4ac_bak;
        return AVERROR_INVALIDDATA;
    }

    skip_bits_long(gb, i);

    switch (m4ac->object_type) {
    case AOT_AAC_MAIN:
    case AOT_AAC_LC:
    case AOT_AAC_SSR:
    case AOT_AAC_LTP:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LD:
        if ((ret = decode_ga_specific_config(ac, avctx, gb, get_bit_alignment,
                                            m4ac, m4ac->chan_config)) < 0)
            return ret;
        break;
    case AOT_ER_AAC_ELD:
        if ((ret = decode_eld_specific_config(ac, avctx, gb,
                                              m4ac, m4ac->chan_config)) < 0)
            return ret;
        break;
    default:
        avpriv_report_missing_feature(avctx,
                                      "Audio object type %s%d",
                                      m4ac->sbr == 1 ? "SBR+" : "",
                                      m4ac->object_type);
        return AVERROR(ENOSYS);
    }

    ff_dlog(avctx,
            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
            m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
            m4ac->sample_rate, m4ac->sbr,
            m4ac->ps);

    return get_bits_count(gb);
}

static int decode_audio_specific_config(AACContext *ac,
                                        AVCodecContext *avctx,
                                        MPEG4AudioConfig *m4ac,
                                        const uint8_t *data, int64_t bit_size,
                                        int sync_extension)
{
    int i, ret;
    GetBitContext gb;

    if (bit_size < 0 || bit_size > INT_MAX) {
        av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n");
        return AVERROR_INVALIDDATA;
    }

    ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3);
    for (i = 0; i < bit_size >> 3; i++)
        ff_dlog(avctx, "%02x ", data[i]);
    ff_dlog(avctx, "\n");

    if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
        return ret;

    return decode_audio_specific_config_gb(ac, avctx, m4ac, &gb, 0,
                                           sync_extension);
}

ff_mpeg4audio_get_config_gb函数参考ffmpeg中的mpeg4audio.c如下:

/*
 * MPEG-4 Audio common code
 * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
 * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "get_bits.h"
#include "mpeg4audio.h"

/**
 * Parse MPEG-4 audio configuration for ALS object type.
 * @param[in] gb       bit reader context
 * @param[in] c        MPEG4AudioConfig structure to fill
 * @return on success 0 is returned, otherwise a value < 0
 */
static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c, void *logctx)
{
    if (get_bits_left(gb) < 112)
        return AVERROR_INVALIDDATA;

    if (get_bits_long(gb, 32) != MKBETAG('A','L','S','\0'))
        return AVERROR_INVALIDDATA;

    // override AudioSpecificConfig channel configuration and sample rate
    // which are buggy in old ALS conformance files
    c->sample_rate = get_bits_long(gb, 32);

    if (c->sample_rate <= 0) {
        av_log(logctx, AV_LOG_ERROR, "Invalid sample rate %d\n", c->sample_rate);
        return AVERROR_INVALIDDATA;
    }

    // skip number of samples
    skip_bits_long(gb, 32);

    // read number of channels
    c->chan_config = 0;
    c->channels    = get_bits(gb, 16) + 1;

    return 0;
}

const uint8_t ff_mpeg4audio_channels[15] = {
    0,
    1, // mono (1/0)
    2, // stereo (2/0)
    3, // 3/0
    4, // 3/1
    5, // 3/2
    6, // 3/2.1
    8, // 5/2.1
    0,
    0,
    0,
    7, // 3/3.1
    8, // 3/2/2.1
    24, // 3/3/3 - 5/2/3 - 3/0/0.2
    8, // 3/2.1 - 2/0
};

static inline int get_object_type(GetBitContext *gb)
{
    int object_type = get_bits(gb, 5);
    if (object_type == AOT_ESCAPE)
        object_type = 32 + get_bits(gb, 6);
    return object_type;
}

static inline int get_sample_rate(GetBitContext *gb, int *index)
{
    *index = get_bits(gb, 4);
    return *index == 0x0f ? get_bits(gb, 24) :
        ff_mpeg4audio_sample_rates[*index];
}

int ff_mpeg4audio_get_config_gb(MPEG4AudioConfig *c, GetBitContext *gb,
                                int sync_extension, void *logctx)
{
    int specific_config_bitindex, ret;
    int start_bit_index = get_bits_count(gb);
    c->object_type = get_object_type(gb);
    c->sample_rate = get_sample_rate(gb, &c->sampling_index);
    c->chan_config = get_bits(gb, 4);
    if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels))
        c->channels = ff_mpeg4audio_channels[c->chan_config];
    else {
        av_log(logctx, AV_LOG_ERROR, "Invalid chan_config %d\n", c->chan_config);
        return AVERROR_INVALIDDATA;
    }
    c->sbr = -1;
    c->ps  = -1;
    if (c->object_type == AOT_SBR || (c->object_type == AOT_PS &&
        // check for W6132 Annex YYYY draft MP3onMP4
        !(show_bits(gb, 3) & 0x03 && !(show_bits(gb, 9) & 0x3F)))) {
        if (c->object_type == AOT_PS)
            c->ps = 1;
        c->ext_object_type = AOT_SBR;
        c->sbr = 1;
        c->ext_sample_rate = get_sample_rate(gb, &c->ext_sampling_index);
        c->object_type = get_object_type(gb);
        if (c->object_type == AOT_ER_BSAC)
            c->ext_chan_config = get_bits(gb, 4);
    } else {
        c->ext_object_type = AOT_NULL;
        c->ext_sample_rate = 0;
    }
    specific_config_bitindex = get_bits_count(gb);

    if (c->object_type == AOT_ALS) {
        skip_bits(gb, 5);
        if (show_bits(gb, 24) != MKBETAG('\0','A','L','S'))
            skip_bits(gb, 24);

        specific_config_bitindex = get_bits_count(gb);

        ret = parse_config_ALS(gb, c, logctx);
        if (ret < 0)
            return ret;
    }

    if (c->ext_object_type != AOT_SBR && sync_extension) {
        while (get_bits_left(gb) > 15) {
            if (show_bits(gb, 11) == 0x2b7) { // sync extension
                get_bits(gb, 11);
                c->ext_object_type = get_object_type(gb);
                if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(gb)) == 1) {
                    c->ext_sample_rate = get_sample_rate(gb, &c->ext_sampling_index);
                    if (c->ext_sample_rate == c->sample_rate)
                        c->sbr = -1;
                }
                if (get_bits_left(gb) > 11 && get_bits(gb, 11) == 0x548)
                    c->ps = get_bits1(gb);
                break;
            } else
                get_bits1(gb); // skip 1 bit
        }
    }

    //PS requires SBR
    if (!c->sbr)
        c->ps = 0;
    //Limit implicit PS to the HE-AACv2 Profile
    if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01)
        c->ps = 0;

    return specific_config_bitindex - start_bit_index;
}

int avpriv_mpeg4audio_get_config2(MPEG4AudioConfig *c, const uint8_t *buf,
                                  int size, int sync_extension, void *logctx)
{
    GetBitContext gb;
    int ret;

    if (size <= 0)
        return AVERROR_INVALIDDATA;

    ret = init_get_bits8(&gb, buf, size);
    if (ret < 0)
        return ret;

    return ff_mpeg4audio_get_config_gb(c, &gb, sync_extension, logctx);
}

具体查看ffmpeg文件,网址:https://github.com/FFmpeg/FFmpeg

5、AAC ES(raw data)

AAC ES是AAC的压缩数据.

5.1 AAC ES存储格式如下:

elementelementChan1elementChan2

5.2 element

element存储格式如下:

element ID (3bits)element tag

AAC元素信息(element)不同,element tag信息不同。具体来说:

在AAC中,原始数据块的组成可能有七种不同的元素:

SCE: Single Channel Element单通道元素。单通道元素基本上只由一个ICS组成。一个原始数据块最可能由16个SCE组成。

CPE: Channel Pair Element 双通道元素,由两个可能共享边信息的ICS和一些联合立体声编码信息组成。一个原始数据块最多可能由16个SCE组成。

CCE: Coupling Channel Element 藕合通道元素。代表一个块的多通道联合立体声信息或者多语种程序的对话信息。

LFE: Low Frequency Element 低频元素。包含了一个加强低采样频率的通道。

DSE: Data Stream Element 数据流元素,包含了一些并不属于音频的附加信息。

PCE: Program Config Element 程序配置元素。包含了声道的配置信息。它可能出现在ADIF 头部信息中。

FIL: Fill Element 填充元素。包含了一些扩展信息。如SBR,动态范围控制信息等。

5.3 elementChan

element不同,包含的elementChan数不同,具体来说elementChan包含数量如下:

elementSCECPECCELFEDSEPCEFILEND
elementChan12010000

每个elementChan数据存储格式如下图:请添加图片描述
具体可以查看ISO/IEC 14496-3之 4.4.2.7


参考资料

[1] : 【网络通信 – 直播】音频流编码 – AAC 基础
https://blog.csdn.net/qq_27788177/article/details/113758541
[2]:AAC 文件解析及解码流程
https://zhuanlan.zhihu.com/p/347992887
[3]:AAC ADTS/LATM格式总结
https://blog.csdn.net/av_geek/article/details/18445347
[4]:ISO/IEC 14496-3
https://csclub.uwaterloo.ca/~ehashman/ISO14496-3-2009.pdf
[5]:ISO/IEC 13818-7
http://www.telemidia.puc-rio.br/~rafaeldiniz/public_files/normas/ISO-13818/ISO_IEC_13818-7_2006(E).pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1411385.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第14章_数据结构与集合源码(一维数组,链表,栈,队列,树与二叉树,List接口分析,Map接口分析,Set接口分析,HashMap的相关问题)

文章目录 第14章_数据结构与集合源码本章专题与脉络1. 数据结构剖析1.1 研究对象一&#xff1a;数据间逻辑关系1.2 研究对象二&#xff1a;数据的存储结构&#xff08;或物理结构&#xff09;1.3 研究对象三&#xff1a;运算结构1.4 小结 2. 一维数组2.1 数组的特点2.2 自定义数…

Linux——系统简介

1、从UNIX到LINUX 在目前主流的服务器端操作系统中&#xff0c;UNIX诞生于20世纪60年代末&#xff0c;Windows诞生于20世纪80年代中期&#xff0c;Linux诞生于20世纪90年代初&#xff0c;可以说UNIX是操作系统中的“老大哥”。 1.1、Linux简史 Linux内核最初是由李纳斯托瓦兹…

Chrony时间同步程序

Chrony简介 学习chrony之前首先要来看看chrony到底是干什么用的&#xff1a; chrony是网络时间协议 &#xff08;NTP&#xff09; 的通用实现。 它可以将系统时钟与 NTP 服务器、参考时钟同步 &#xff08;例如 GPS 接收器&#xff09;&#xff0c;以及使用手表和键盘手动输入…

vue3---inputRef.value.focus()报错Cannot read properties of null (reading ‘focus‘)

问题描述&#xff1a;点击编辑按钮&#xff0c;出现el-input框&#xff08;el-input显示隐藏通过v-if控制&#xff09; <el-input ref"inputRef" v-if"isEdit" v-model"modelName" blur"isEdit false" /> <el-button text …

机器学习_常见算法比较模型效果(LR、KNN、SVM、NB、DT、RF、XGB、LGB、CAT)

文章目录 KNNSVM朴素贝叶斯决策树随机森林 KNN “近朱者赤&#xff0c;近墨者黑”可以说是 KNN 的工作原理。 整个计算过程分为三步&#xff1a; 计算待分类物体与其他物体之间的距离&#xff1b;统计距离最近的 K 个邻居&#xff1b;对于 K 个最近的邻居&#xff0c;它们属于…

【Maven教程】(十五):编写 Maven 插件—— 编写 Maven 插件的一般步骤及案例、Mojo 标注与参数、错误处理和日志 ~

Maven 编写 Maven 插件 1️⃣ 编写 Maven 插件的一般步骤2️⃣ 案例&#xff1a;编写一个用于代码行统计的 Maven 插件3️⃣ Mojo 标注4️⃣ Mojo 参数5️⃣ 错误处理和日志6️⃣ 测试 Maven 插件&#x1f33e; 总结 前面文章已经讲过&#xff0c;Maven 的任何行为都是由插件完…

[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

如何使用Flutter构建高质量的用户界面

Flutter 是一种比较流行的移动应用开发框架&#xff0c;可以让开发者使用一个代码库构建高质量的 iOS 和 Android 应用。Flutter 以其快速、美观、高度可定制等优点吸引了开发社区的广泛关注。但如何使用 Flutter 构建高质量的用户界面呢&#xff1f;下面分为以下几个部分简单的…

聚醚醚酮(Polyether Ether Ketone)PEEK主要作用是什么?

聚醚醚酮&#xff08;Polyether Ether Ketone&#xff0c;PEEK&#xff09;在工程和高性能应用中具有广泛的应用&#xff0c;主要作用包括&#xff1a; 1.结构材料&#xff1a; PEEK因其优异的机械性能&#xff0c;包括高强度、高硬度和耐磨性&#xff0c;常被用作结构件的制造…

企业能源消耗监测管理系统是否可以做好能源计量与能耗分析?

能源消耗与分析是能源科学管理的基础&#xff0c;也可促进能源管理工作的改善&#xff0c;在企业中能源管理系统的作用也愈加重要。 首先&#xff0c;能源计量是能源管理的基础&#xff0c;通过能源精准计老化&#xff0c;容易出现测量设备不准确以及其他一些人为因素原因导致…

蓝凌OA sysUiExtend.do 任意文件上传漏洞复现

0x01 产品简介 蓝凌核心产品EKP平台定位为新一代数字化生态OA平台,数字化向纵深发展,正加速构建产业互联网,对企业协作能力提出更高要求,蓝凌新一代生态型OA平台能够支撑办公数字化、管理智能化、应用平台化、组织生态化,赋能大中型组织更高效的内外协作与管理,支撑商业…

编译PCL Qt程序

使用PCL的qt程序时&#xff0c;提示不是用QVTK编译的&#xff0c;所以需要在编译VTK时打开Qt的编译选项&#xff08;由于CMakeList比较复杂&#xff0c;使用CMakeGui进行配置&#xff0c;PCL同理&#xff09;&#xff0c;编译VTK完成后&#xff0c;编译PCL也需要配置Qt支持&…

【VTKExamples::PolyData】第十九期 ImplicitDataSetClipping

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例ImplicitDataSetClipping,并解析接口vtkIdFilter & vtkBox & vtkClipPolyData,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就…

Pandas ------ 向 Excel 文件中写入含有合并表头的数据

Pandas ------ 向 Excel 文件中写入含有合并表头的数据 推荐阅读引言正文 推荐阅读 Pandas ------ 向 Excel 文件中写入含有 multi-index 和 Multi-column 表头的数据 引言 这里给大家介绍一下如何向 Excel 中写入带有合并表头的数据。 正文 import pandas as pddf1 pd.D…

flutter设置windows是否显示标题栏和状态栏和全屏显示

想要让桌面软件实现全屏和不显示状态栏或者自定义状态栏&#xff0c;就可以使用window_manager这个依赖库&#xff0c;使用起来还是非常方便的&#xff0c;可以自定义显示窗口大小和位置&#xff0c;还有设置标题栏是否展示等内容&#xff0c;也可以设置可拖动区域。官方仓库地…

C语言实现希尔排序算法(附带源代码)

希尔排序 希尔排序&#xff0c;也称递减增量排序算法&#xff0c;是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的&#xff1a; 插入排序在对几乎已经排好序的数据操作时&#xff0c;效率高&#xff0…

Unity配置表xlsx/xls打包后读取错误问题

前言 代码如下&#xff1a; //文本解析private void ParseText(){//打开文本 读FileStream stream File.Open(Application.streamingAssetsPath excelname, FileMode.Open, FileAccess.Read, FileShare.Read);//读取文件流IExcelDataReader excelRead ExcelReaderFactory…

2011-2022年北大数字普惠金融指数“第五期”(包括省市县)

2011-2022年北大数字普惠金融指数“第五期”&#xff08;包括省市县&#xff09; 1、时间&#xff1a;2011-2022年 其中县级的时间为2014-2022年 2、来源&#xff1a;北大数字普惠金融指数 3、范围&#xff1a;全国31省&#xff0c;337个地级市以及2800个县 4、指标&#x…

利用nginx宝塔免费防火墙实现禁止国外IP访问网站

本章教程&#xff0c;主要介绍&#xff0c;如何利用nginx宝塔面板中的插件免费防火墙&#xff0c;实现一键禁止国外IP访问网站。 目录 一、安装宝塔插件 二、 开启防火墙 一、安装宝塔插件 在宝塔面板中的软件商店&#xff0c;搜索防火墙关键词&#xff0c;找到Nginx免费防火…

Windows 上面双网卡网络,配置为优先IPV4

多数网络游戏加速器是不支持IPV6的&#xff0c;即便支持IPV6也不好用&#xff0c;原因是IPV6在大陆并不是普及的状态&#xff0c;很多资源是没有的。 所以本文会教大家怎么让双IP栈的用户&#xff0c;怎么配置优先适用IPV4&#xff0c;并且IPV6也还可以用。 跟着我的步骤来&am…