[音视频学习笔记]八、FFMpeg结构体分析 -上一个项目用到的数据结构简单解析:AVFrame、AVFormatContext、AVCodecContext

前言

上次我们做了一个简单的视频解码,MediaPlay-FFmpeg - Public 这一次简单对这个代码进行一个剖析,对其中的数据结构进行一个解析。

这些数据结构之间的关系

AVFrame 、AVFormatContext 、AVCodecContext 、AVIOContext 、AVCodec 、AVStream 、AVPacket

最关键的结构体可以分成以下几类:

1. 解协议(http,rtsp,rtmp,mms)

AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)

2. 解封装(flv,avi,rmvb,mp4)

AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。

3. 解码(h264,mpeg2,aac,mp3)

每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。

4. 存数据

视频的话,每个结构一般是存一帧;音频可能有好几帧

解码前数据:AVPacket

解码后数据:AVFrame

他们之间的对应关系如下所示:

在这里插入图片描述

AVFrame

AVFrame是包含码流参数较多的结构体。本文将会详细分析一下该结构体里主要变量的含义和作用。

首先看一下结构体的定义(位于avcodec.h):

AVFrame结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来说是PCM),此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP表,运动矢量表等数据。编码的时候也存储了相关的数据。因此在使用FFMPEG进行码流分析的时候,AVFrame是一个很重要的结构体。

下面看几个主要变量的作用(在这里考虑解码的情况):

uint8_t *data[AV_NUM_DATA_POINTERS]:解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)int linesize[AV_NUM_DATA_POINTERS]:data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。int width, height:视频帧宽和高(1920x1080,1280x720...int nb_samples:音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个int format:解码后原始数据类型(YUV420,YUV422,RGB24...int key_frame:是否是关键帧enum AVPictureType pict_type:帧类型(I,B,P...)AVRational sample_aspect_ratio:宽高比(16:94:3...int64_t pts:显示时间戳int coded_picture_number:编码帧序号int display_picture_number:显示帧序号int8_t *qscale_table:QP表uint8_t *mbskip_table:跳过宏块表int16_t (*motion_val[2])[2]:运动矢量表uint32_t *mb_type:宏块类型表short *dct_coeff:DCT系数,这个没有提取过int8_t *ref_index[2]:运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)int interlaced_frame:是否是隔行扫描uint8_t motion_subsample_log2:一个宏块中的运动矢量采样个数,取log的

具体细节说明:

1.data[]

对于packed格式的数据(例如RGB24),会存到data[0]里面。

对于planar格式的数据(例如YUV420P),则会分开成data[0],data[1],data[2]…(YUV420P中data[0]存Y,data[1]存U,data[2]存V)

取帧转换相关的内容详情参考 : [音视频学习笔记]一、YUV和RGB像素数据的常见处理

2. pict_type

包含以下类型:

enum AVPictureType {AV_PICTURE_TYPE_NONE = 0, ///< 未定义AV_PICTURE_TYPE_I,     ///< I帧AV_PICTURE_TYPE_P,     ///< P帧AV_PICTURE_TYPE_B,     ///< B帧AV_PICTURE_TYPE_S,     ///< S帧AV_PICTURE_TYPE_SI,    ///< SI 帧AV_PICTURE_TYPE_SP,    ///< SP 帧AV_PICTURE_TYPE_BI,    ///< BI 帧
};
3. sample_aspect_ratio

采样宽高比:

宽高比是一个分数,FFMPEG中用AVRational表达分数:

/*** 有理数分子/分母*/
typedef struct AVRational{int num; ///< 分子int den; ///< 分母
} AVRational;
4. qscale_table

QP表指向一块内存,里面存储的是每个宏块的QP值。宏块的标号是从左往右,一行一行的来的。每个宏块对应1个QP。

qscale_table[0]就是第1行第1列宏块的QP值;qscale_table[1]就是第1行第2列宏块的QP值;qscale_table[2]就是第1行第3列宏块的QP值。以此类推…

宏块的个数用下式计算:

注:宏块大小是16x16的。

每行宏块数:

int mb_stride = pCodecCtx->width/16+1

宏块的总数:

int mb_sum = ((pCodecCtx->height+15)>>4)*(pCodecCtx->width/16+1)
5. motion_subsample_log2

1个运动矢量所能代表的画面大小(用宽或者高表示,单位是像素),注意,这里取了log2。

代码注释中给出以下数据:

4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2

即1个运动矢量代表16x16的画面的时候,该值取4;1个运动矢量代表8x8的画面的时候,该值取3…以此类推

6. motion_val

运动矢量表存储了一帧视频中的所有运动矢量。

该值的存储方式比较特别:

int16_t (*motion_val[2])[2];

注释中给了一段代码:

int mv_sample_log2= 4 - motion_subsample_log2;
int mb_width= (width+15)>>4;
int mv_stride= (mb_width << mv_sample_log2) + 1;
motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];

大概知道了该数据的结构:

1.首先分为两个列表L0和L1

2.每个列表(L0或L1)存储了一系列的MV(每个MV对应一个画面,大小由motion_subsample_log2决定)

3.每个MV分为横坐标和纵坐标(x,y)

注意,在FFMPEG中MV和MB在存储的结构上是没有什么关联的,第1个MV是屏幕上左上角画面的MV(画面的大小取决于motion_subsample_log2),第2个MV是屏幕上第1行第2列的画面的MV,以此类推。因此在一个宏块(16x16)的运动矢量很有可能如下图所示(line代表一行运动矢量的个数):

//例如8x8划分的运动矢量与宏块的关系://-------------------------//|          |            |//|mv[x]     |mv[x+1]     |//-------------------------//|          |	          |//|mv[x+line]|mv[x+line+1]|//-------------------------
7. mb_type

宏块类型表存储了一帧视频中的所有宏块的类型。其存储方式和QP表差不多。只不过其是uint32类型的,而QP表是uint8类型的。每个宏块对应一个宏块类型变量。

宏块类型如下定义所示:

//The following defines may change, don't expect compatibility if you use them.
#define MB_TYPE_INTRA4x4   0x0001
#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
#define MB_TYPE_INTRA_PCM  0x0004 //FIXME H.264-specific
#define MB_TYPE_16x16      0x0008
#define MB_TYPE_16x8       0x0010
#define MB_TYPE_8x16       0x0020
#define MB_TYPE_8x8        0x0040
#define MB_TYPE_INTERLACED 0x0080
#define MB_TYPE_DIRECT2    0x0100 //FIXME
#define MB_TYPE_ACPRED     0x0200
#define MB_TYPE_GMC        0x0400
#define MB_TYPE_SKIP       0x0800
#define MB_TYPE_P0L0       0x1000
#define MB_TYPE_P1L0       0x2000
#define MB_TYPE_P0L1       0x4000
#define MB_TYPE_P1L1       0x8000
#define MB_TYPE_L0         (MB_TYPE_P0L0 | MB_TYPE_P1L0)
#define MB_TYPE_L1         (MB_TYPE_P0L1 | MB_TYPE_P1L1)
#define MB_TYPE_L0L1       (MB_TYPE_L0   | MB_TYPE_L1)
#define MB_TYPE_QUANT      0x00010000
#define MB_TYPE_CBP        0x00020000
//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)

一个宏块如果包含上述定义中的一种或两种类型,则其对应的宏块变量的对应位会被置1。
注:一个宏块可以包含好几种类型,但是有些类型是不能重复包含的,比如说一个宏块不可能既是16x16又是8x8。

8. ref_index

运动估计参考帧列表存储了一帧视频中所有宏块的参考帧索引。这个列表其实在比较早的压缩编码标准中是没有什么用的。只有像H.264这样的编码标准才有多参考帧的概念。但是这个字段目前我还没有研究透。只是知道每个宏块包含有4个该值,该值反映的是参考帧的索引。以后有机会再进行细研究吧。

使用解析:

我们在使用的时候,主要是使用avcodec_receive_frame函数,将packet解码成AVFrame数据,然后通过sws_scale转换成RGB数据,然后将获得的二进制数据转换成一张照片进行播放。

大概流程:

...
AVFrame* ptr_avframe, * ptr_avframeRGB = nullptr;
...//初始化数据帧空间
ptr_avframe = av_frame_alloc();
ptr_avframeRGB = av_frame_alloc();//av_image_get_buffer_size一帧大小buf = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB32, ptr_avctx->width, ptr_avctx->height, 1));av_image_fill_arrays(ptr_avframeRGB->data, ptr_avframeRGB->linesize, buf, AV_PIX_FMT_RGB32, ptr_avctx->width, ptr_avctx->height, 1);...//解码视频数据AVCodecContext
ret = avcodec_receive_frame(ptr_avctx, ptr_avframe);...
// 处理解码后的图像帧
sws_scale(ptr_swsCtx, (const unsigned char* const*)ptr_avframe->data, ptr_avframe->linesize, 0, ptr_avctx->height, ptr_avframeRGB->data, ptr_avframeRGB->linesize);...
//释放资源
av_frame_free(&ptr_avframeRGB);
av_frame_free(&ptr_avframe);

AVCodecContext

AVCodecContext是包含变量较多的结构体(感觉差不多是变量最多的结构体)。本文将会大概分析一下该结构体里每个变量的含义和作用。因为如果每个变量都分析的话,工作量太大,实在来不及。
首先看一下结构体的定义(位于avcodec.h):

主要挑一些常用参数

enum AVMediaType codec_type:编解码器的类型(视频,音频...struct AVCodec  *codec:采用的解码器AVCodec(H.264,MPEG2...int bit_rate:平均比特率uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)int width, height:如果是视频的话,代表宽和高int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)int sample_rate:采样率(音频)int channels:声道数(音频)enum AVSampleFormat sample_fmt:采样格式int profile:型(H.264里面就有,其他编码标准应该也有)int level:级(和profile差不太多)

在这里需要注意:AVCodecContext中很多的参数是编码的时候使用的,而不是解码的时候使用的。

1. codec_type

编解码器类型有以下几种:

enum AVMediaType {AVMEDIA_TYPE_UNKNOWN = -1,  ///< Usually treated as AVMEDIA_TYPE_DATAAVMEDIA_TYPE_VIDEO,AVMEDIA_TYPE_AUDIO,AVMEDIA_TYPE_DATA,          ///< Opaque data information usually continuousAVMEDIA_TYPE_SUBTITLE,AVMEDIA_TYPE_ATTACHMENT,    ///< Opaque data information usually sparseAVMEDIA_TYPE_NB
};

2. sample_fmt

在FFMPEG中音频采样格式有以下几种:

enum AVSampleFormat {AV_SAMPLE_FMT_NONE = -1,AV_SAMPLE_FMT_U8,          ///< unsigned 8 bitsAV_SAMPLE_FMT_S16,         ///< signed 16 bitsAV_SAMPLE_FMT_S32,         ///< signed 32 bitsAV_SAMPLE_FMT_FLT,         ///< floatAV_SAMPLE_FMT_DBL,         ///< doubleAV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planarAV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planarAV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planarAV_SAMPLE_FMT_FLTP,        ///< float, planarAV_SAMPLE_FMT_DBLP,        ///< double, planarAV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

3. profile

在FFMPEG中型有以下几种,可以看出AAC,MPEG2,H.264,VC-1,MPEG4都有型的概念。

#define FF_PROFILE_UNKNOWN -99
#define FF_PROFILE_RESERVED -100#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW  1
#define FF_PROFILE_AAC_SSR  2
#define FF_PROFILE_AAC_LTP  3
#define FF_PROFILE_AAC_HE   4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD   22
#define FF_PROFILE_AAC_ELD  38#define FF_PROFILE_DTS         20
#define FF_PROFILE_DTS_ES      30
#define FF_PROFILE_DTS_96_24   40
#define FF_PROFILE_DTS_HD_HRA  50
#define FF_PROFILE_DTS_HD_MA   60#define FF_PROFILE_MPEG2_422    0
#define FF_PROFILE_MPEG2_HIGH   1
#define FF_PROFILE_MPEG2_SS     2
#define FF_PROFILE_MPEG2_SNR_SCALABLE  3
#define FF_PROFILE_MPEG2_MAIN   4
#define FF_PROFILE_MPEG2_SIMPLE 5#define FF_PROFILE_H264_CONSTRAINED  (1<<9)  // 8+1; constraint_set1_flag
#define FF_PROFILE_H264_INTRA        (1<<11) // 8+3; constraint_set3_flag#define FF_PROFILE_H264_BASELINE             66
#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
#define FF_PROFILE_H264_MAIN                 77
#define FF_PROFILE_H264_EXTENDED             88
#define FF_PROFILE_H264_HIGH                 100
#define FF_PROFILE_H264_HIGH_10              110
#define FF_PROFILE_H264_HIGH_10_INTRA        (110|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_HIGH_422             122
#define FF_PROFILE_H264_HIGH_422_INTRA       (122|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_HIGH_444             144
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE  244
#define FF_PROFILE_H264_HIGH_444_INTRA       (244|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_CAVLC_444            44#define FF_PROFILE_VC1_SIMPLE   0
#define FF_PROFILE_VC1_MAIN     1
#define FF_PROFILE_VC1_COMPLEX  2
#define FF_PROFILE_VC1_ADVANCED 3#define FF_PROFILE_MPEG4_SIMPLE                     0
#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE            1
#define FF_PROFILE_MPEG4_CORE                       2
#define FF_PROFILE_MPEG4_MAIN                       3
#define FF_PROFILE_MPEG4_N_BIT                      4
#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE           5
#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION      6
#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE     7
#define FF_PROFILE_MPEG4_HYBRID                     8
#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME         9
#define FF_PROFILE_MPEG4_CORE_SCALABLE             10
#define FF_PROFILE_MPEG4_ADVANCED_CODING           11
#define FF_PROFILE_MPEG4_ADVANCED_CORE             12
#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
#define FF_PROFILE_MPEG4_SIMPLE_STUDIO             14
#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE           15

使用解析

AVCodeContext主要通过AVFormatContext来查找到需要的编码器,来解码视频数据

...
AVCodecContext* ptr_avctx = nullptr;
...
//获取视频流编码
ptr_avctx = avcodec_alloc_context3(nullptr);...//查找编码器avcodec_parameters_to_context(ptr_avctx, ptr_formatCtx->streams[streamIndex]->codecpar);ptr_codec = avcodec_find_decoder(ptr_avctx->codec_id);...
avcodec_close(ptr_avctx);...
if (avcodec_open2(ptr_avctx, ptr_codec, nullptr) < 0) {avcodec_close(ptr_avctx);
...
buf = (unsigned char*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB32, ptr_avctx->width, ptr_avctx->height, 1));av_image_fill_arrays(ptr_avframeRGB->data, ptr_avframeRGB->linesize, buf, AV_PIX_FMT_RGB32, ptr_avctx->width, ptr_avctx->height, 1);

AVFormatContext

AVFormatContext是包含码流参数较多的结构体。
在使用FFMPEG进行开发的时候,AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数。它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体。下面看几个主要变量的作用(在这里考虑解码的情况):

AVIOContext *pb:输入数据的缓存unsigned int nb_streams:视音频流的个数AVStream **streams:视音频流char filename[1024]:文件名int64_t duration:时长(单位:微秒us,转换为秒需要除以1000000int bit_rate:比特率(单位bps,转换为kbps需要除以1000)AVDictionary *metadata:元数据

视频的时长可以转换成HH:MM:SS的形式,示例代码如下:

AVFormatContext *pFormatCtx;
CString timelong;
...
//duration是以微秒为单位
//转换成hh:mm:ss形式
int tns, thh, tmm, tss;
tns  = (pFormatCtx->duration)/1000000;
thh  = tns / 3600;
tmm  = (tns % 3600) / 60;
tss  = (tns % 60);
timelong.Format("%02d:%02d:%02d",thh,tmm,tss);

视频的原数据(metadata)信息可以通过AVDictionary获取。元数据存储在AVDictionaryEntry结构体中,如下所示

typedef struct AVDictionaryEntry {char *key;char *value;
} AVDictionaryEntry;

每一条元数据分为key和value两个属性。
在ffmpeg中通过av_dict_get()函数获得视频的原数据。

下列代码显示了获取元数据并存入meta字符串变量的过程,注意每一条key和value之间有一个"\t:“,value之后有一个”\r\n"

//MetaData------------------------------------------------------------
//从AVDictionary获得
//需要用到AVDictionaryEntry对象
//CString author,copyright,description;
CString meta=NULL,key,value;
AVDictionaryEntry *m = NULL;
//不用一个一个找出来
/*	m=av_dict_get(pFormatCtx->metadata,"author",m,0);
author.Format("作者:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"copyright",m,0);
copyright.Format("版权:%s",m->value);
m=av_dict_get(pFormatCtx->metadata,"description",m,0);
description.Format("描述:%s",m->value);
*/
//使用循环读出
//(需要读取的数据,字段名称,前一条字段(循环时使用),参数)
while(m=av_dict_get(pFormatCtx->metadata,"",m,AV_DICT_IGNORE_SUFFIX)){key.Format(m->key);value.Format(m->value);meta+=key+"\t:"+value+"\r\n" ;
}

调用示例

...
AVFormatContext* ptr_formatCtx = nullptr;...//创建AVFormatContext
ptr_formatCtx = avformat_alloc_context();
...//初始化ptr_formatCtx 
if (avformat_open_input(&ptr_formatCtx, videopath, nullptr, nullptr) != 0) {qDebug() << "AVFormat open input Error";return -1;
}//获取音频流数据信息
if (avformat_find_stream_info(ptr_formatCtx, nullptr) < 0) {avformat_close_input(&ptr_formatCtx);qDebug() << "AVFormat find stream info Error";return -2;
}...
for (int i = 0; i < ptr_formatCtx->nb_streams; ++i) {if (ptr_formatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {streamIndex = i;blnVideo = true;break;}
}
...
//查找编码器
avcodec_parameters_to_context(ptr_avctx, ptr_formatCtx->streams[streamIndex]->codecpar);...if (av_read_frame(ptr_formatCtx, ptr_avpkg) >= 0) {	//读取一帧未解码的数据...avformat_close_input(&ptr_formatCtx);

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

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

相关文章

CentOS7.x 上安装并配置 MySQL 8.x

如何在 CentOS 7 上安装并配置 MySQL 8.x MySQL 是最流行的开源关系型数据库管理系统之一&#xff0c;被广泛应用于各种网站和应用程序中。 步骤 1&#xff1a;下载并添加 MySQL 8.x 官方 Yum 仓库 首先&#xff0c;打开终端&#xff0c;下载 MySQL Yum 仓库的 rpm 包&#…

Redis 服务器指南:高性能内存数据库的完整使用指南

Redis 服务器是一个基于内存的键值存储数据库&#xff0c;具有高性能和丰富的数据结构支持。 Redis 服务器的基本使用方法 安装 Redis Redis 可以通过官方网站下载源码进行编译安装&#xff0c;也可以通过包管理工具直接安装。 在 Ubuntu 上&#xff0c;可以使用以下命令进…

从政府工作报告中的IT热词统计探计算机行业发展(三)智能网联新能源汽车:2次

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

3.24作业

基于UDP的网络聊天室 项目需求&#xff1a; 如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息如果有人下线&#xff0c;其他用户可以收到这个人的下线信息服务器可以发送系统信息 服务器端代码 #in…

智能小程序开发 —— P2P SDK 源码介绍(四)

ty.p2p.onDownloadTotalProgressUpdate 下载总进度回调 需引入P2PKit&#xff0c;且在>2.0.3版本才可使用 参数 function callback 下载总进度回调的回调函数 回调参数 Object res 属性类型默认值必填说明deviceIdstring是设备idprogressnumber是上传/下载进度 函数定…

matlab-双树复小波变换DTCWT(转自 MathWorks)

此示例展示了双树复小波变换 (DTCWT) 如何在信号、图像和体积处理方面提供优于临界采样 DWT 的优势。DTCWT 作为两个独立的双通道滤波器组来实现。为了获得本示例中描述的优点&#xff0c;您不能任意选择两个树中使用的缩放和小波滤波器。一棵树的低通&#xff08;缩放&#xf…

3.25 ARM day8

1.自己设置温度湿度阈值&#xff0c;当温度过高时&#xff0c;打开风扇&#xff0c;蜂鸣器报警 2.当湿度比较高时&#xff0c;打开LED1灯&#xff0c;蜂鸣器报警 bee.c #include"bee.h" void bee_init() {RCC->MP_AHB4ENSETR | (0x1<<1);GPIOB->MODE…

Github多账号共存

在开发阶段&#xff0c;如果同时拥有多个开源代码托管平台的账户&#xff0c;在代码的管理上非常麻烦。那么&#xff0c;如果同一台机器上需要配置多个账户&#xff0c;怎样才能确保不冲突&#xff0c;不同账户独立下载独立提交呢&#xff1f; 我们以两个github账号进行演示 …

【工作中问题解决实践 十三】线上JVM参数该如何配置

在线上部署Java应用时&#xff0c;可以通过Java虚拟机&#xff08;JVM&#xff09;的参数来控制内存的分配和管理。 常见的JVM配置参数 以下是一些常见的JVM内存参数&#xff1a; -Xms&#xff1a; 设置JVM的初始堆大小。 重点关注-Xmx&#xff1a; 设置JVM的最大堆大小。 重…

docker desktop启动Kibana:No living connections, Error: No Living connections

Kibana启动之后一直报Kibana server is not ready yet 查看日志&#xff1a;No living connections, Error: No Living connections,连接ES失败&#xff01; 查看配置文件内容 /usr/share/kibana/config/kibana.yml 经过一系列查找资料和尝试之后&#xff0c;亲测以下方法可用…

阿里二面:谈谈ThreadLocal的内存泄漏问题?问麻了。。。。

引言 ThreadLocal在Java多线程编程中扮演着重要的角色&#xff0c;它提供了一种线程局部存储机制&#xff0c;允许每个线程拥有独立的变量副本&#xff0c;从而有效地避免了线程间的数据共享冲突。ThreadLocal的主要用途在于&#xff0c;当需要为每个线程维护一个独立的上下文…

字节算法岗二面,凉凉。。。

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总…

华为OD技术面算法题整理

LeetCode原题 简单 题目编号频次409. 最长回文串 - 力扣(LeetCode)3

JSONObject优雅获取深层字段属性值

开篇说明 如果在这里获得过启发和思考&#xff0c;希望点赞支持&#xff01;对于内容有不同的看法欢迎来信交流。 技术栈 >> java 邮箱 >> 15673219519163.com 描述介绍 根据JSONObject中字段的名称,优雅获取深层属性值 使用示例,取error_entry的数量。JSON的层…

分治归并问题

“别让自我被拯救~” 谈谈归并与分治 当我们首次接触排序算法时&#xff0c;一定对所谓 "归并"方式排序的算法感到头疼~ 因为&#xff0c;我们难以形象出其不断 "分离"时&#xff0c;各个区域的状态。然而&#xff0c;即便 "归并"排序算法的学习…

新能源汽车充电桩消防安全视频智能可视化监管建设方案

一、方案背景 据应急管理部门统计公布的数据显示&#xff0c;仅2023年第一季度&#xff0c;新能源汽车自燃率就上涨了32%&#xff0c;平均每天就有8辆新能源汽车发生火灾&#xff08;含自燃&#xff09;。在已查明起火原因中&#xff0c;58%源于电池问题&#xff0c;19%源于碰…

输出当前时间

用途&#xff1a;在项目中一些属性中设置当前时间 实例代码 import java.time.LocalDateTime; import java.time.format.DateTimeFormatter;public class time {public static void main(String[] args){LocalDateTime china LocalDateTime.now(); DateTimeFormatter forma…

ASPICE学习笔记 ———— 过程模型(Process reference model)

文章目录 介绍过程模型Primary life cycle processes categoryAcquisition Process GroupSupply Process GroupSystem Engineering Processes GroupSoftware Engineering Processes Group Supporting life cycle processes categoryOrganizational life cycle processes catego…

动态规划算法入门

动态规划算法入门 动态规划(Dynamic Programming, DP)是一种常用的算法设计技术,它通过将原问题分解为相对简单的子问题,并存储子问题的解来避免重复计算,最终获得原问题的最优解。本文将通过实例来介绍动态规划的基本原理和思路。 一、动态规划的基本思想 动态规划的基本思…

【活动预告】本周四(3月28日)AI算法大模型备案线上活动

Al算法备案中心特邀十年合规专家「乐歌」&#xff0c;于本周四进行线上算法备案活动 支持AI创业者&#xff0c;免费咨询算法备案 3.28日20&#xff1a;00腾讯会议欢迎参与&#xff01; 扫码添加活动助理报名参加&#xff01;