11 - FFmpeg - 编码 AAC
Planar 模式是 ffmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。
FFmpeq解码不同格式的音频输出的音频采样格式不是一样。
其中AAC解码输出的数据为浮点型的 AV_SAMPLE_FMT_FLTP 格式,MP3 解码输出的数据为 AV_SAMPLE_FMT_S16P 格式(使用的mp3文件为16位深)。
具体采样格式可以査看解码后的 AVframe 中的 format 成员或解码器的AVCodecContext中的sample_fmt成员。
Planar或者Packed模式直接影响到保存文件时写文件的操作,操作数据的时候一定要先检测音频采样格式。
方法1
int encodeAudioInterface(AVCodecContext *encoderCtx, AVFrame *frame, AVPacket *packet, FILE *dest_fp)
{int ret = avcodec_send_frame(encoderCtx, frame);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "send frame to encoder failed:%s\n", av_err2str(ret));ret = -1;}while (ret >= 0){ret = avcodec_receive_packet(encoderCtx, packet);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){av_log(NULL, AV_LOG_WARNING, "[encodeAudioInterface] -- AVERROR(EAGAIN) || AVERROR_EOF \n");return 0;}else if (ret < 0){av_log(NULL, AV_LOG_ERROR, "encode frame failed:%s\n", av_err2str(ret));return -1;}fwrite(packet->data, 1, packet->size, dest_fp);av_packet_unref(packet);}return 0;
}
int encodeAudio(const char *inFileName, const char *outFileName)
{int ret = 0;/*****************************************************************************/FILE *src_fp = fopen(inFileName, "rb");if (src_fp == NULL){av_log(NULL, AV_LOG_ERROR, "open infile:%s failed!\n", inFileName);ret = -1;goto end;}FILE *dest_fp = fopen(outFileName, "wb+");if (dest_fp == NULL){av_log(NULL, AV_LOG_ERROR, "open outfile:%s failed!\n", outFileName);ret = -1;goto end;}/*****************************************************************************/AVFrame *frame = av_frame_alloc();frame->sample_rate = 48 * 1000; // 采样率 - 48Kframe->channels = 2;frame->channel_layout = AV_CH_LAYOUT_STEREO;frame->format = AV_SAMPLE_FMT_S16;frame->nb_samples = 1024;// libfdk_aacav_frame_get_buffer(frame, 0);AVCodec *encoder = avcodec_find_encoder_by_name("libfdk_aac");if (encoder == NULL){av_log(NULL, AV_LOG_ERROR, "find encoder failed!\n");ret = -1;goto end;}AVCodecContext *encoderCtx = avcodec_alloc_context3(encoder);if (encoderCtx == NULL){av_log(NULL, AV_LOG_ERROR, "alloc encoder context failed!\n");ret = -1;goto end;}encoderCtx->sample_fmt = frame->format;encoderCtx->sample_rate = frame->sample_rate;encoderCtx->channels = frame->channels;encoderCtx->channel_layout = frame->channel_layout;ret = avcodec_open2(encoderCtx, encoder, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "open encoder failed:%s\n", av_err2str(ret));goto end;}AVPacket packet;av_init_packet(&packet);while (1){// packet L R L R// 2 * 2 * 1024 = 4096int readSize = fread(frame->data[0], 1, frame->linesize[0], src_fp);if (readSize == 0){av_log(NULL, AV_LOG_INFO, "finish read infile!\n");break;}encodeAudioInterface(encoderCtx, frame, &packet, dest_fp);}encodeAudioInterface(encoderCtx, NULL, &packet, dest_fp);end:if (frame){av_frame_free(&frame);}if (encoderCtx){avcodec_free_context(&encoderCtx);return ret;}if (src_fp){fclose(src_fp);}if (dest_fp){fclose(dest_fp);}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
方法 2
int CheckSampleRate(const AVCodec *encoder, const int SampleRate)
{// encoder->supported_samplerates 支持的音频采样数组,如果未知则为NULL,数组以0结尾const int *SupportSampleRate = encoder->supported_samplerates;while (*SupportSampleRate != 0){av_log(NULL, AV_LOG_DEBUG, "[%s] encoder->name: %s, support %d hz -- line:%d\n", __FUNCTION__, encoder->name, *SupportSampleRate, __LINE__); // 受 frame->format等参数影响if (*SupportSampleRate == SampleRate){av_log(NULL, AV_LOG_INFO, "[%s] This sampling rate is supported by the encoder %d hz -- line:%d\n", __FUNCTION__, *SupportSampleRate, __LINE__); // 受 frame->format等参数影响return 1;}SupportSampleRate++;}return 0;
}
int CheckChannelLayout(const AVCodec *encoder, const uint64_t ChannelLayout)
{// 支持通道布局的数组,如果未知则为NULL。数组以0结尾const uint64_t *SupportsChannelLayout = encoder->channel_layouts;if (!SupportsChannelLayout){ // 不是每个AVCodec都给出支持的channel_layoutav_log(NULL, AV_LOG_WARNING, "[%s] the encoder %s no set channel_layouts -- line:%d\n", __FUNCTION__, encoder->name, __LINE__);return 1;}while (*SupportsChannelLayout != 0){av_log(NULL, AV_LOG_DEBUG, "[%s] encoder->name: %s, support channel_layout %ld -- line:%d\n", __FUNCTION__, encoder->name, *SupportsChannelLayout, __LINE__); // 受 frame->format等参数影响if (*SupportsChannelLayout == ChannelLayout){av_log(NULL, AV_LOG_INFO, "[%s] This channel layout is supported by the encoder %d -- line:%d\n", __FUNCTION__, *SupportsChannelLayout, __LINE__); // 受 frame->format等参数影响return 1;}*SupportsChannelLayout++;}return 0;
}
int CheckSampleFmt(const AVCodec *codecCtx, enum AVSampleFormat SampleFmt)
{ // 数组支持的样例格式,如果未知则为NULL,数组以-1结尾const enum AVSampleFormat *SampleFmts = codecCtx->sample_fmts;while (*SampleFmts != AV_SAMPLE_FMT_NONE) // 通过 AV_SAMPLE_FMT_NONE 作为结束{if (*SampleFmts == SampleFmt){return 1;}*SampleFmts++;}return 0;
}
void GetAdtsHeader(AVCodecContext *codecCtx, uint8_t *adtsHeader, int aacLength)
{uint8_t freqIdx = 0; // 0: 96000HZ 3:48000Hz 4:44100Hzswitch (codecCtx->sample_rate){case 96000:freqIdx = 0;break;case 88200:freqIdx = 1;break;case 64000:freqIdx = 2;break;case 48000:freqIdx = 3;break;case 44100:freqIdx = 4;break;case 32000:freqIdx = 5;break;case 24000:freqIdx = 6;break;case 22050:freqIdx = 7;break;case 16000:freqIdx = 8;break;case 12000:freqIdx = 9;break;case 11025:freqIdx = 10;break;case 8000:freqIdx = 11;break;case 7350:freqIdx = 12;break;default:freqIdx = 4;break;}uint8_t chanCfg = codecCtx->channels;uint32_t frameLength = aacLength + 7;adtsHeader[0] = 0xff;adtsHeader[1] = 0xF1;adtsHeader[2] = ((codecCtx->profile) << 6) + (freqIdx << 2) + (chanCfg >> 2);adtsHeader[3] = (((chanCfg & 3) << 6) + (frameLength >> 11));adtsHeader[4] = ((frameLength & 0x7FF) >> 3);adtsHeader[5] = (((frameLength & 7) << 5) + 0x1F);adtsHeader[6] = 0xFC;
}
int decodeAudioInterface(AVCodecContext *codecCtx, AVFrame *frame, AVPacket *pkt, FILE *output)
{int ret = avcodec_send_frame(codecCtx, frame);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] sending the frame to the encoder error! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}// 编码和解码都是一样的,都是send 1次,然后 receive 多次,直到AVERROR(EAGAIN)或者AVERROR_EOFwhile (ret >= 0){ret = avcodec_receive_packet(codecCtx, pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){return 0;}else if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] encoding audio frameerror! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}uint8_t aacHeader[7];GetAdtsHeader(codecCtx, aacHeader, pkt->size);size_t len = fwrite(aacHeader, 1, 7, output);if (len != 7){av_log(NULL, AV_LOG_ERROR, "[%s] fwrite aac_header failed! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}len = fwrite(pkt->data, 1, pkt->size, output);if (len != pkt->size){av_log(NULL, AV_LOG_ERROR, "[%s] fwrite aac data failed! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}}return -1;
}
void f32leConvert2fltp(float *f32le, float *fltp, int nb_samples)
{float *fltp_l = fltp; // 左通道float *fltp_r = fltp + nb_samples; // 右声道for (int i = 0; i < nb_samples; i++){fltp_l[i] = f32le[i * 2]; // 1 0 - 2 3fltp_r[i] = f32le[i * 2 + 1]; // 可以尝试注释左声道或者右声道听听声音}
}
int decodeAudio(const char *pcmFileName, const char *aacFileName, const char *encoderName)
{FILE *pcmfile = fopen(pcmFileName, "rb");FILE *aacfile = fopen(aacFileName, "wb");if (pcmfile == NULL || aacfile == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] open %s or %s file failed -- line:%d \n", __FUNCTION__, aacFileName, pcmFileName, __LINE__);goto _end;}const AVCodec *encoder = NULL;if (encoderName != NULL && (strcmp(encoderName, "libfdk_aac") == 0 || strcmp(encoderName, "aac") == 0)) // encoderName 如果制定了编码器{encoder = avcodec_find_encoder_by_name(encoderName); // 设置为指定编码器av_log(NULL, AV_LOG_INFO, "[%s] force codec name: %s -- line:%d\n", __FUNCTION__, encoderName, __LINE__);}else{encoder = avcodec_find_encoder(AV_CODEC_ID_AAC);av_log(NULL, AV_LOG_INFO, "[%s] default codec name: %s -- line:%d\n", __FUNCTION__, "aac", __LINE__);}if (encoder == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] Codec found error! -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}// 创建编码器上下文AVCodecContext *codecCtx = avcodec_alloc_context3(encoder);if (codecCtx == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] Conld not allocate audio codec context -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}codecCtx->codec_id = AV_CODEC_ID_AAC;codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;codecCtx->bit_rate = 128 * 1024;codecCtx->channel_layout = AV_CH_LAYOUT_STEREO;codecCtx->sample_rate = 48000;codecCtx->channels = av_get_channel_layout_nb_channels(codecCtx->channel_layout);codecCtx->profile = FF_PROFILE_AAC_LOW;if (strcmp(encoder->name, "libfdk_aac") == 0){codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;}else{codecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;}// 检测采样格式的支持情况if (!CheckSampleFmt(encoder, codecCtx->sample_fmt)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample format %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(codecCtx->sample_fmt), __LINE__);goto _end;}if (!CheckSampleRate(encoder, codecCtx->sample_rate)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample rate codecCtx->sample_rate:%d -- line:%d\n", __FUNCTION__, codecCtx->sample_rate, __LINE__);goto _end;}if (!CheckChannelLayout(encoder, codecCtx->channel_layout)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample channel_layout %lu -- line:%d\n", __FUNCTION__, codecCtx->channel_layout, __LINE__);goto _end;}av_log(NULL, AV_LOG_INFO, "\n[%s] ------------------------ Audio encode config ------------------------ line:%d \n", __FUNCTION__, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->bit_rate: %ld kbps -- line:%d\n", __FUNCTION__, codecCtx->bit_rate / 1024, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->sample_rate: %d -- line:%d\n", __FUNCTION__, codecCtx->sample_rate, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->sample_fmt: %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(codecCtx->sample_fmt), __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->channels: %d -- line:%d\n", __FUNCTION__, codecCtx->channels, __LINE__);// frame_size 是在 av_coedc_open2后进行关联av_log(NULL, AV_LOG_INFO, "[%s] Before frame size %d -- line:%d\n", __FUNCTION__, codecCtx->frame_size, __LINE__);if (avcodec_open2(codecCtx, encoder, NULL) < 0){av_log(NULL, AV_LOG_ERROR, "[%s] Could not open codec -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}av_log(NULL, AV_LOG_INFO, "[%s] Once frame_size %d -- line:%d\n\n", __FUNCTION__, codecCtx->frame_size, __LINE__); // 决定每次送多少个采样点AVPacket *packet = av_packet_alloc();if (!packet){av_log(NULL, AV_LOG_ERROR, "[%s] packet alloc error! -- line:%d \n", __FUNCTION__, __LINE__);goto _end;}AVFrame *frame = av_frame_alloc();if (!frame){av_log(NULL, AV_LOG_ERROR, "[%s] Could not allocate audio frame -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}frame->nb_samples = codecCtx->frame_size;frame->format = codecCtx->sample_fmt;frame->channel_layout = codecCtx->channel_layout;frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout);av_log(NULL, AV_LOG_INFO, "[%s] frame nb_samples: %d -- line:%d\n", __FUNCTION__, frame->nb_samples, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] frame sample_fmt: %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(frame->format), __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] frame channel_layout: %lu -- line:%d\n", __FUNCTION__, frame->channel_layout, __LINE__);// 为frame分配bufferint ret = av_frame_get_buffer(frame, 0);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] Could not allocate audio data buffers -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}// 计算出每一帧的数据 单个采样点的字节 * 通道数目 * 每帧采样点的数量size_t FrameByteSize = av_get_bytes_per_sample(frame->format) * frame->channels * frame->nb_samples;av_log(NULL, AV_LOG_INFO, "[%s] frame_bytes %ld frame->channels %d frame->nb_samples %d -- line:%d\n", __FUNCTION__, FrameByteSize, frame->channels, frame->nb_samples, __LINE__);uint8_t *pcmBuf = (uint8_t *)malloc(FrameByteSize);uint8_t *pcmBufTemp = (uint8_t *)malloc(FrameByteSize);if (!pcmBuf || !pcmBufTemp){av_log(NULL, AV_LOG_ERROR, "[%s] pcmBuf or pcmBufTemp malloc failed -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}memset(pcmBuf, 0, FrameByteSize);memset(pcmBufTemp, 0, FrameByteSize);int64_t pts = 0;av_log(NULL, AV_LOG_INFO, "\n[%s] ------------------------ start enode ------------------------ line:%d \n", __FUNCTION__, __LINE__);while (1){memset(pcmBuf, 0, FrameByteSize);size_t ReadByteSize = fread(pcmBuf, 1, FrameByteSize, pcmfile);if (ReadByteSize <= 0){av_log(NULL, AV_LOG_INFO, "[%s] read file finish -- line:%d \n", __FUNCTION__, __LINE__);break;}/*确保该 frame 可写, 如果编码器内部保持了内存参数计数,则需要重新拷贝一个备份目的是新写入的数据和编码器保存的数据不能产生冲突*/ret = av_frame_make_writable(frame);if (ret != 0){av_log(NULL, AV_LOG_ERROR, "[%s] av_frame_make_writable failed!!! -- line:%d\n", __FUNCTION__, __LINE__);}if (AV_SAMPLE_FMT_S16 == frame->format){// 将读取到的PCM数据填充到frame去,但是要注意匹配格式,(planner | packet )ret = av_samples_fill_arrays(frame->data, frame->linesize, pcmBuf, frame->channels, frame->nb_samples, frame->format, 0);}else{// 将读取到的PCM数据填充到frame去,但是要注意匹配格式,(planner | packet )// 将本地的f32le packed 模式的数据转为 float palannermemset(pcmBufTemp, 0, FrameByteSize);f32leConvert2fltp((float *)pcmBuf, (float *)pcmBufTemp, frame->nb_samples);ret = av_samples_fill_arrays(frame->data, frame->linesize, pcmBufTemp, frame->channels, frame->nb_samples, frame->format, 0);}// 设置 ptspts += frame->nb_samples;frame->pts = pts; // 使用采样率作为pts的单位,具体换算成秒 pts*1/采样率ret = decodeAudioInterface(codecCtx, frame, packet, aacfile);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] encode failed -- line:%d\n", __FUNCTION__, __LINE__);break;}}/*冲刷编码器*/decodeAudioInterface(codecCtx, NULL, packet, aacfile);
_end:if (aacfile){fclose(aacfile);}if (pcmfile){fclose(pcmfile);}if (pcmBuf){free(pcmBuf);}if (pcmBufTemp){free(pcmBufTemp);}if (packet){av_packet_free(&packet);}if (frame){av_frame_free(&frame);}if (codecCtx){avcodec_free_context(&codecCtx);}return ret;
}
对于 flush encoder 的操作:
编码器通常的冲洗方法:调用一次 avcodec_send_frame(NULL)(返回成功),
然后不停调用 avcodec_receive_packet() 直到其返回 AVERROR_EOF,取出所有缓存帧,
avcodec_receive_packet() 返回 AVERROR EOF 这一次是没有有效数据的,仅仅获取到一个结束标志
相关文章:
11 - FFmpeg - 编码 AAC
Planar 模式是 ffmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。 FFmpeq解码不同格式的音频输出的音频采样格式不是一样。 其中AAC解码输出的数据为浮点型的 AV_SAMPLE_FMT_FLTP 格式,MP3 解码输出的数据为 AV_SAMPLE_FMT_S16P 格式(使用的…...

OS Copilot初体验的感受与心得
本文介绍体验操作系统智能助手OS Copilot后,个人的一些收获、体验等。 最近,抽空体验了阿里云的操作系统智能助手OS Copilot,在这里记录一下心得与收获。总体观之,从个人角度来说,感觉这个OS Copilot确实抓住了不少开发…...
Ajax学习笔记
文章目录标题 Ajax学习笔记axios使用axios请求拦截器axios响应拦截器优化axios响应结果 form-serialize插件图片上传HTTP协议请求报文相应报文接口文档 AJAX原理 - XMLHttpRequest使用XMLHttpRequestXMLHttpRequest - 查询参数查询字符串对象 XMLHttpRequest - 数据提交 事件循…...
医学深度学习与机器学习融合的随想
医学深度学习与机器学习融合的随想 近年来,深度学习(图像类)和机器学习在医学领域的应用取得了飞速发展,为医学影像分析、疾病诊断和预后预测等领域带来了革命性的变革。深度学习擅长从复杂数据中提取高层次特征,而机…...
坑人的macos tar 命令 (实际上是bsdtar)换用 gnu tar
周末 看着笔记本上好用的朗文当代高级词典(mac版)和其它两部词典,准备复制到黑苹果台式机上去。考虑到词典内容有太多小文件,普通复制传输太慢,毫无疑问用 tar 打包肯定快而且能保留原始文件的各种信息。命令如下: time tar czf …...

【SpringBoot3】全局异常处理
【SpringBoot3】全局异常处理 一、全局异常处理器step1:创建收入数字的页面step2:创建控制器,计算两个整数相除step3:创建自定义异常处理器step5:创建给用提示的页面step6:测试输入(10/0) 二、BeanValidato…...
vue-Treeselect
一、Node KeyTypeDescriptionid (required)Number | String用于标识树中的选项。其值在所有选项中必须是唯一的label (required)String用于显示选项childrennode[] | null声明一个分支节点。你可以: 1) 设置为由a组成的子选项数组。叶节点,b…...
【机器学习框架TensorFlow和PyTorch】基本使用指南
机器学习框架TensorFlow和PyTorch:基本使用指南 目录 引言TensorFlow概述 TensorFlow简介TensorFlow的基本使用 PyTorch概述 PyTorch简介PyTorch的基本使用 TensorFlow和PyTorch的对比结论 引言 随着深度学习的快速发展,机器学习框架在实际应用中起到…...
matlab 中的methods(Access = protected) 是什么意思
gpt版本 在 MATLAB 中,methods 是用于定义类方法的一部分。(Access protected) 是一种访问控制修饰符,它限制了方法的访问权限。具体来说,当你在类定义中使用 methods(Access protected) 时,你是在定义只有类本身及其子类可以访…...

【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)
0x01 产品简介 NETGEAR WN604是一款由NETGEAR(网件)公司生产的无线接入器(或无线路由器)提供Wi-Fi保护协议(WPA2-PSK, WPA-PSK),以及有线等效加密(WEP)64位、128位和152…...
图像处理 -- ISP调优(tuning)的步骤整理
ISP调优流程培训文档 1. 硬件准备 选择合适的图像传感器:根据项目需求选择合适的传感器型号。搭建测试环境:包括测试板、光源、色彩卡和分辨率卡等。 2. 初始设置 寄存器配置:初始化传感器的寄存器设置,包括曝光、增益、白平衡…...

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.2系统架构
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...

node.js中nodemon : 无法加载和使用问题,这是由于windows安全策略影起的按如下操作即可
1、用管理员权限打开vscode 2、文件终端中打开,输入 Set-ExecutionPolicy -Scope CurrentUser 3、再输入RemoteSigned 4、使用get-ExecutionPolicy查看权限,可以看到变为了RemoteSigned 重启问题解决...

【SD】 Stable Diffusion(SD)原理详解与ComfyUI使用 2
Stable Diffusion(SD)原理详解与ComfyUI使用 Stable Diffusion(SD)原理详解与ComfyUI使用1. SD整体结构2. Clip(文本编码器)3. Unit(生成模型)4. VAE(变分自编码器&#…...

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(七)-广播远程识别码(Broadcast Remote ID)
目录 引言 5.5 广播远程识别码(Broadcast Remote ID) 5.5.1 使用PC5的广播远程识别码 5.5.2 使用MBS的广播远程识别码 引言 3GPP TS 23.256 技术规范,主要定义了3GPP系统对无人机(UAV)的连接性、身份识别、跟踪及…...
VMware 虚拟机 ping 不通原因排查
目录 一、检查网络 二、重启虚拟机网络 因为最近遇到了一个比较奇怪的 ping 不通虚拟机的事,在此过程中,检查了很多的设置,故而写一篇文章记录下,如有 VMware 虚拟机 ping 不通可以尝试本文的排查方式。 下面以 VMware 虚拟机为…...

websocket状态机
websocket突破了HTTP协议单向性的缺陷,基于HTTP协议构建了双向通信的通道,使服务端可以主动推送数据到前端,解决了前端不断轮询后台才能获取后端数据的问题,所以在小程序和H5应用中被广泛使用。本文主要集合报文分析对于websocket…...

JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】
JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】 目录 JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现CPO-Transformer-LSTM多变量回归预测…...

力扣3226 使两个整数相等的位更改次数
写的代码: class Solution { public:string cc(int num){string res"";while(num>0){int rnum % 2;resstatic_cast<char>(48r)res;num/2;}return res;}int minChanges(int n, int k) {int res0;string n2cc(n);string k2cc(k);int n_sizen2.siz…...

VLAN 划分案例详解
vlan 的应用在网络项目中是非常广泛的,基本上大部分的项目都需要划分 vlan,这里从基础的 vlan 的知识开始,了解 vlan 的划分原理。 为什么需要 vlan: 1、什么是 VLAN? VLAN(Virtual LAN)&…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...