以FLV解复用为例详解开源库FFmpeg中解复用器的源码逻辑及处理流程

news2024/12/23 9:07:22

目录

1、FFmpeg简介

2、FLV文件格式介绍

3、注册解复用器

4、解复用器的处理

4.1、AVFormatContext

4.1.1、AVClass

4.1.2、AVOption

4.1.3    AVDictionary—AV字典

4.1.4、AVIOContext

4.1.4.1、URLProtocol

4.1.4.2、AVIOContext的初始化及获取

4.1.5、AVInputFormat

4.1.6、AVStream

4.2、解复用器的获取

4.3、Flv解复用器处理流程分析

4.3.1、读取头信息--flv_read_header

4.3.2、AVStream的获取--flv_read_packet

5、总结


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(专栏文章已更新400多篇,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.htmlC++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_2276111.html一般音视频编解码器处理的是原始的裸音视频数据(编码器对原始音视频数据进行编码,解码器从编码后的音视频数据中解析出原始的音视频数据)。flv/avi/mp4等格式文件中包含的是编码后的音视频数据,解复用的目的就是从封装容器中解析出各音频流或视频流等。本文以FLV解复用器分析ffmpeg解复用的处理逻辑,介绍了ffmeg中解复用器的注册,并以FLV解复用器为例分析解复用器如何从封装格式中,解析出不同的视频、音频、数据流。

1、FFmpeg简介

FFmpeg是一个开源的多媒体框架,广泛用于处理音视频处理领域。它提供了一套丰富的工具和库,支持广泛的多媒体格式的解码、编码、转码、等功能。支持多种格式的音视频编码和解码,以及音视频的转换、剪辑、过滤、流处理等功能。

FFmpeg主要特性如下:

1)音视频编解码

  • FFmpeg包含了非常先进的音频/视频编解码库libavcodec,其中很多codec都是从头开发的,以保证高可移植性和编解码质量。
  • 支持几乎所有的音视频格式和编解码器,包括常见的MP4、AVI、MOV、MKV、FLV、MP3、AAC等文件封装格式,以及H.264、H.265、AAC、VP9、AV1等音视频编解码器。

2)音视频处理

  • 提供了丰富的音视频处理功能,如去噪、模糊视频、色彩转换、视频旋转、提取帧、缩放视频尺寸等。
  • 可以通过其提供的滤镜库libavfilter对音视频数据进行各种处理,如缩放、裁剪、添加水印等。

3)流媒体处理

  • FFmpeg支持将本地音视频文件转换为流媒体格式,并通过网络进行传输和播放。
  • 完全支持使用HLS和MPEG-DASH打包视频,并可以配置为使用RTMP或其他协议来传输视频。

4)封装与解封装

  • 提供了对各种音视频封装格式的读写支持,如MP4、FLV等。
  • AVFormat模块封装了Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透明的。

5)高效稳定
FFmpeg在音视频处理方面表现出色,具有高效且稳定的性能,能够处理大量的音视频数据。
6)开源

FFmpeg采用LGPL或GPL许可证,其开源属性意味着任何人都能修改并使用它。
7)跨平台

FFmpeg可以在多种操作系统上运行,包括但不限于Linux、Windows、macOS等,这使其具有非常广泛的适用性。
8)社区支持

作为一个开源项目,FFmpeg拥有活跃的社区,用户可以从社区获得帮助和最新的开发动态。

几乎所有的视频播放器都使用到了FFmpeg的音视频解码功能,比如国内知名的暴风影音、QQ影音、腾讯视频、爱奇艺视频、优酷视频等。

FFmpeg内部支持多种音视频格式之间的相互转换,很多音视频转化软件都用到了FFmpeg的音视频转换功能,比如大家常用的格式工厂、暴风转码(暴风影音自带的工具)、QQ音影自带的视频格式转换工具、狸窝视频转换器、迅捷视频转换器等。    

2、FLV文件格式介绍

FLV视频格式是Adobe公司设计开发的一种流媒体的封装格式,总体上看,FLV包括文件头(Flv Header)和文件体(Flv Body)两部分,其中文件体由一系列的Tag及Tag Size对组成。Tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。

header部分记录了flv的类型、版本等信息,是flv的开头,一般都差不多,占9bytes。具体格式如下:

body部分由一个个Tag组成,每个Tag的下面有一块4bytes的空间,用来记录这个tag的长度,这个后置用于逆向读取处理。 每个Tag由也是由两部分组成的:Tag Header和Tag Data。Tag Header里存放的是当前Tag的类型、数据区(Tag Data)长度等信息,具体如下:

3、注册解复用器

调用av_register_all()接口注册所有格式的编解码器和复用/解复用器、硬件加速器、解析等。调用关系图如下:

所有的注册逻辑都是相同的,注册解复用也一样,其链表头为first_iformat:
Ffmpeg/libavformat/allformats.c

 真正实现注册解复用器的函数是av_register_input_format(),如下:
Ffmpeg/libavformat/formats.c

由此可以看出,所有解复用器按注册的先后顺序以链表结构存储起来,链表头为first_iformat。以注册flv、avi为例:

First_iformat是AVInputFormat*类型指针,指向第一个注册的flv解复用器ff_flv_demuxer,flv解复用器对象的next变量(AVInputFormat*类型)指向avi解复用器对象ff_avi_demuxer,依次向后。
需要注意的是,ff_flv_demuxer、ff_avi_demuxer都是按AVInputFormat结构定义好的解复用器对象,以flv为例:
Flv解复用:Ffmpeg/libavformat/flvdec.c

通过上面的分析,向ffmpeg注册新的解码器的步骤如下:

1)在/libavformat下,创建源文件,在该源文件中按AVInputFormat类型接口定义该算法处理。
2)调用REGISTER_DEMUXER宏,注册该解码器。


       在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:该精品技术专栏的订阅量已达到510多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,预计更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法,详细讲述了C++软件的调试方法与手段,以图文并茂的方式给出具体的项目问题实战分析实例(很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力!所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:  

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795

常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏3:(本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,专栏文章已经更新到400多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点(模版泛型编程、STL容器及算法函数的使用等)、C++11及以上新特性(不仅看开源代码会用到,日常编码中也会用到部分新特性,面试时也会涉及到)、常用C++开源库的介绍与使用、代码分享(调用系统API、使用开源库)、常用编程技术(动态库、多线程、多进程、数据库及网络编程等)、软件UI编程(Win32/duilib/QT/MFC)、C++软件调试技术(排查软件异常的手段与方法、分析C++软件异常的基础知识、常用软件分析工具使用、实战问题分析案例等)、设计模式、网络基础知识与网络问题分析进阶内容等。

专栏4:   

VC++常用功能开发汇总(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5: 

C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


4、解复用器的处理

解复用器处理过程中,涉及到若干结构体类型,这里先介绍下。

4.1、AVFormatContext

媒体封装上下文,包含如下成员,下面我们分析这几个结构体类型:

4.1.1、AVClass

AVClass是一个成员管理系统,记录了其关联类的类名、并通过其AVOption对象设置关联类的成员变量等,AVFormatContext、AVIOContext、AVCodecContext等都有其对应的AVClass成员管理对象AVFormatContext对象调用avformat_get_context_defaults()接口初始化默认值时,将其av_class对象指向全局的AVClass对象av_format_context_class, av_format_context_class的AVOption成员option指向全局的avformat_options数组,这里列出一部分如下:
/ffmpeg/libavformat/options.c

 /ffmpeg/libavformat/options_table.h

AVFormatContext、AVClass与AVOption之间的关系如下:

图中AVFormatContext结构体的第一个变量为AVClass类型的指针av_class,它在AVFormatContext结构体初始化的时候,被赋值指向了全局静态变量av_format_context_class结构体(定义位于libavformat\options.c)。而AVClass类型的av_format_context_class结构体中的option变量指向了全局静态数组avformat_options(定义位于libavformat\options_table.h)。
Ps:应该也可以自定义一个AVClass及AVOption对象,赋给AVFormatContext。

4.1.2、AVOption

AVClass中存储了AVOption类型的option数组,用于存储AVClass关联类的成员变量信息,每一个成员变量对应一个AVOption。可以使用av_opt_set()函数通过字符串的方式(传入参数为变量名称的字符串和变量值的字符串)设置AVOption的值。
/ffmpeg/libavutil/opt.c

该函数首先通过av_opt_find2()在**(AVClass**)obj中查找到与name匹配的AVOption对象o,然后根据该对象的类型o->type调用相应的类型设置函数(如set_string_bool、set_string、set_string_image_size等),将字符串val转换为相应type的数据并对该AVOption对象o进行赋值。
Ps: av_opt_get通过字符串获取变量值:

4.1.3    AVDictionary—AV字典

AVDictionary键值对类型,结构体定义如下:
/ffmpeg/libavutil/dict.c

/ffmpeg/libavutil/dict.h

这里介绍设置键值和获取键值的两个接口
/ffmpeg/libavutil/dict.h

功能:将键值对(key, value)添加到pm中,如果pm为*pm为NULL,将会创建一个新的AVDictionaryEntry对象并将该对象地址赋值给*pm
/ffmpeg/libavutil/dict.h

功能:在m中遍历,获得匹配key值的AVDictionaryEntry对象(即返回值)。

4.1.4、AVIOContext

协议(文件)操作的顶层结构是AVIOContext,这个对象实现了带缓冲的读写操作;FFMPEG的输入对象AVFormat的pb字段指向一个AVIOContext。

AVIOContext的opaque实际指向一个URLContext对象,这个对象封装了协议对象及协议操作对象,其中prot指向具体的协议操作对象,priv_data指向具体的协议对象。

URLProtocol为协议操作对象,针对每种协议,会有一个这样的对象,每个协议操作对象和一个协议对象关联,比如,文件操作对象为ff_file_protocol,它关联的结构体是FileContext。

4.1.4.1、URLProtocol

URLProtocol是FFMPEG操作文件的结构(包括文件,网络数据流等等),包括open、close、read、write、seek等操作。
在在av_register_all()函数中,通过调用REGISTER_PROTOCOL()宏,所有的URLProtocol都保存在以first_protocol为链表头的链表中
/ffmpeg/libavformat/url.h

以file文件为例:

查看file_open发现, ff_file_protocol操作的FileContext数据就是URLContext的priv_data

4.1.4.2、AVIOContext的初始化及获取

/ffmpeg/libavformat/aviobuf.c

从上图发现,最终实现AVIOContext初始化并获取对文件对象的是ffio_open_whitelist。

4.1.5、AVInputFormat

从前文了解到AVInputFormat实际上就是解复用器结构类型,各类型的解复用器已经在av_register_all()是注册成全局的链表,表头为first_iformat。以flv为例:
/ffmpeg/libavformat/flvdec.c

  • .name:解复用器名称
  • .long_name:对应的文件格式
  • .priv_date_size:该解复用器关联的文件结构体类型
  • .read_probe:检测输入AVProbeData文件名数据与该解复用器的匹配度
  • .read_header:
  • .read_packet:
  • .read_seek:
  • .extensions:后缀名

后边几个函数分别为探测、读取头信息、读取包信息、搜索、关闭,从这几个函数的源代码可以看出,解复用器处理的FLVContext数据指针保存在其关联AVFormatContext->priv_data中。

4.1.6、AVStream

AVStream是存储媒体流信息的结构体,其初始化函数avformat_new_stream(),解复用器负责把不同媒体流从容器(媒体文件)中解析出来并保存到不同的AVStream中。

4.2、解复用器的获取

AVInputFormat解复用器对象的获取有两种方法:

1)由文件名获取:/ffmpeg/libavformat/utils.cinit_input()

​Pd中包含了文件名,由文件名检测出对应的解复用器。

av_probe_input_format2调用av_probe_input_format3,在av_probe_input_format3中,遍历所有注册的解复用器fmt1(AVInputFormat),对于每个解复用器fmt1,调用fmt1的检测函数read_probe检测其与文件名的匹配度,如果没有该函数,则通过fmt1的后缀名extensions匹配。

​2)如果文件名检测不出来,则通过AVIOContext获取:/ffmpeg/libavformat/utils.cinit_input()

​s->pb为解复用器AVInputFormat对象所在AVFormatContext对象的AVIOContext成员,其获取方法如下:

在av_probe_input_buffer2函数中,实际上也是通过avio_read接口从s->pb中得到媒体相关的AVProbeData数据,然后再调用av_probe_input_format2接口(即方法一),获得解复用器。需要注意的是:

i)s->io_open在s(AVFormatContext类型)初始化时构建
/ffmpeg/libavformat/options.c

​查看io_open_default发现,该函数调用的是ffio_open_whitelist函数,由3.1.4.2可知正是该函数根据文件名获取了其对应的AVIOContext对象pb。

ii)方法一和方法二虽然最终都调用av_probe_input_format2检测,但在该函数中看,方法一、二的参数和处理流程是不一样的。

​/ffmpeg/libavformat/avformat.h 

​方法一中,pd = {filename, NULL, 0} 因为pd->buf = NULL,所以调用fmt1->read_probe是检测不到对应的解复用器的,只能通过pd->filename和fmt1->extensions比较得到结果。

方法二中,pd = {filename, buf, 0} ,其中buf是在av_probe_input_buffer2中调用avio_read获取的。由于pd->buf不为NULL,所以在fmt1->read_probe可检测到其对应的解复用器。

4.3、Flv解复用器处理流程分析

Flv解复用器按照flv文件格式解析出数据,根据不同的音频、视频数据,创建出对应的AVStream并记录到AVFormatContext中。这里介绍主要的两个函数

4.3.1、读取头信息--flv_read_header

/ffmpeg/libavformat/flvdec.c

​首先我们要知道s->pb是AVIOContext,该结构体中存在一个读写指针buf_ptr记录当前文件的读写位置。下面我们对每行代码进行分析:

line632:s->priv_data在avformat_open_input函数中被指向ff_flv_demuxer.priv_class即flv_class(参           看ff_flv_demuxer定义),显然这里flv_class应该是在初始化FLVContext对象时,被赋值给FLVContext成员管理对象的,但是我没有找到FLVContext初始化的地方。

/ffmpeg/libavformat/utils.c

Line635:跳过4个字节
Line636:读取1个字节,也就是第5个字节,对照FLV文件格式,我们发现改字节记录了流信息
Line640:读取4个字节,获取header长度
Line641:从文件开始,跳过文件头Header,到FLV body部分
Line642:跳过4个字节,这4个字节记录上一个Tag的大小即表中的PreTagSize0

到这里flv_read_header就结束了,我们发现该函数的作用仅仅是把读写指针buf_ptr指向flv的第一个有效媒体数据部分即Tag0。
需要说明的是,不同媒体格式的处理都不一样,avi的avi_read_header函数,就实现了AVStream的创建即参数设置,而FLV的AVStream则是在flv_read_packet()中创建的。

4.3.2、AVStream的获取--flv_read_packet

该函数代码较多,这里分析主要代码行
/ffmpeg/libavformat/flvdec.c

Line850:获取AVIOContext当前读写位置
Line851:读1字节,该字节标识当前tag是音频流(8)/视频流(9)/脚本数据(18)
Line853:3字节,记录数据区长度
Line854:记录已经读取的所有tag总长度
Line855:获取时间戳(3字节)
Line856:获取扩展时间戳(1字节)并和line855行获取的时间戳组合成完整的时间戳
Line860:跳过3个字节(这3个字节为streamid),读写指针指向数据区TagData

Line886:根据Line851获取的type,判断该tag是否为音频数据
Line888:读1个字节flags,该字节高4位标识音频格式、2-3两位标识采样率,最后两位分别标识位宽和声道
Line890:根据type判断该tag是否为视频数据
Line892:读1字节flags,该字节高4位标识帧类型(I/P/B),低四位标识视频格式
Line896-901:脚本数据,flv_read_metabody函数获取码流宽高等信息,并保持到AVFormatContext

通过以上两段代码的分析,我们发现flv解复用器所做的操作都是按照flv语法获取数据,很显然其他解复用器也是同样的原理。

Line936-950:遍历已有的AVStream队列,查找和当前tag数据类型相同的AVStream流,显然从tag1开始处理时,是没有AVStream队列的,应该跳转到Line951行
Line940:根据Line888得到的flags,获取音频解码器id(st->codecpar->codec_id),如AV_CODEC_ID_AAC
Line944:根据Line892得到的flags,获取视频解码器id(st->codecpar->codec_id),如AV_CODEC_ID_H264
Line954:根据Line887/891的stream_type创建并初始化AVStream流。查看create_stream函数发现,该函数就是通过avformat_new_stream创建的AVStream对象。

Line1009-1012:根据flags获取音频通道数channels、采样率sample_rate和位宽bits_per_coded_sample
Line1015-1025:更新创建的AVStream流的解码器参数信息

Line1042:设置AVStream的视频解码器信息

 
Line1112:读取tagData数据到AVPacktet
Line1115:设置解码时间戳dts
Line1116:设置显示时间戳pts
Line1117:设置该AVPacket所在的AVStream队列

flv_read_header()和flv_read_packet()两个函数基本完成了flv媒体的解复用功能,这两个函数分别在avformat_open_input()和avformat_find_stream_info()两个接口中用到,并完成对AVFormatContext和AVStream信息的赋值。

调用avformat_open_input()获取的信息如下:通过之前的分析,我们知道flv_read_header没有获取信息,仅仅是移动了读写指针。

​调用avformat_find_stream_info()获取的信息如下,该函数中会调用flv_read_packet(),并解析相关数据,可以完整填充AVFormatContext和AVStream信息:

​至此,解复用器逻辑分析结束。

       以上代码截图中的代码查看工具是Source Insight,该工具是轻量级的代码查看与编辑工具,虽不能编译代码,但查看和编辑代码很方便,我们经常使用该工具去查看开源代码。关于如何使用Source Insight工具,可以查看我之前写的文章:

如何使用 Source Insight 查看编辑C/C++源代码?icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124347857

5、总结

简单来讲,解复用器功能就是获取音视频码流所需解码器,在读取包AVPacket后,根据数据包AVPacket所在流AVStream,找到对应的解码器进行解码。

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

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

相关文章

基于vue篮球联盟管理系统pf

TOC springboot476基于vue篮球联盟管理系统pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现,改变了几千年以来人们的生活,不仅仅是生活物资的丰富,还有精神层次的丰富。在互联网诞生之前,地域位置往往是人们思想上不可跨域…

Python入门教程(超详细)

《网络安全自学教程》 Python是一种「基于C语言」实现的,「开源」的,「面向对象的」的,「动态数据类型」的「解释型」语言。 Python的语法「简单」且「优雅」,相对于其他语言学习「难度较低」,入门非常快。 Python的…

【C++】使用红黑树封装map与set

文章目录 1. 源码分析2. 调整红黑树的结构搭建map、set3. 红黑树的迭代器3.1 普通迭代器3.2 const迭代器3.3 map的operator[ ] 4. 完整代码4.1 RBTree4.2 MyMap4.3 MySet 对于map与set,它们一个是KV模型,一个是K模型,那我们要写两个红黑树吗&…

基于Springboot网上蛋糕售卖店管理系统的设计与实现--论文pf

TOC springboot504基于Springboot网上蛋糕售卖店管理系统的设计与实现--论文pf 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和…

解决springboot中Aspect注解不生效问题

如下图所示,配置了一个注解类型的Aspect,结果一直不生效 运行结果可以看到,其他非注解类型的Aspect都顺利执行了,但是这个注解的切面就是没有执行 当时也在网上搜了半天,包括在启动类增加配置,接口都要加上…

Java语言程序设计基础篇_编程练习题**16.30(模式识别:连续四个相同的数)

目录 题目:**16.30(模式识别:连续四个相同的数) 习题思路 代码示例 结果展示 题目:**16.30(模式识别:连续四个相同的数) 为编程练习题8.19编写一个GUI程序。让用户在6行7列的网格的…

实时手势识别(2)- 基于关键点分类实现零样本图片的任意手势的识别

目录 前言 1.实现效果 2.关键点分类网络 3.KPNet训练测试数据准备 4.训练结果 4.1训练过程可视化 4.2验证集上的混淆矩阵 4.测试结果 4.1不同规模模型的测试结果对比 4.2分类结果投影到第一象限 4.3测试集上的混淆矩阵 4.4 二义性手势结果 4.5视频实测 5.零样本的…

深入理解计算机系统 CSAPP 实验lab:Architecture Lab

前期准备参考: 深入理解计算机系统 CSAPP 第四章 Y86-64模拟器 安装与使用-CSDN博客 writeup上写了要求,这里就不赘述了. Part A: sum.ys: # Execution begins at address 0 .pos 0irmovq stack, %rsp # Set up stack pointercall main # Execute main programhalt # …

【CRT实用小技巧(1)】一键发送命令到所有会话窗口

CRT实用小技巧(1)一键发送命令到所有会话窗口 在view(视图)中打开command windows(命令窗口) 打开后,可以看到下面的命令窗口了 然后再下面的命令窗口中,右键出菜单,选择…

centos7突然掉电后启动报错/dev/mapper/centos-root does not exist

问题现象 物理服务器SR588已安装centos7,突然掉电后系统进不去,提示/dev/mapper/centos-root does not exist 问题解决过程 网上搜索相关的解决方法 1、 用此方法不行 2、 用此方法也是不行 3、 分析查看ls /dev/mapper,目录底下没有cent…

Kafka运行机制(一):Kafka集群启动,controller选举,生产消费流程

前置知识 Kafka基本概念https://blog.csdn.net/dxh9231028/article/details/141270920?spm1001.2014.3001.5501 1. Kafka集群启动 Kafka在启动集群中的各个broker时,broker会向controller注册自己,并且从controller节点同步集群元数据。 broker是Kaf…

栈和堆的区别

存储内容不同: 栈区:主要存储函数调用时的局部变量、函数参数等。栈底是函数调用后的下一条指令。 堆区:存储动态分配的内存,如使用 new 分配的内存,具体内容由程序员安排。 管理方式不同: 栈区&#x…

牛客刷题二叉树(三)

1.输出二叉树的右视图 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** 求二叉树的右视图* param preOrder int整型一维数组 先序遍历* param inOrder int整型一维数组 中序…

【无线通信发展史⑤】万有引力定律的推导前奏3.0,本次学习开普勒三大定律,成就“天空立法者”的美名

前言:用这几个问答形式来解读下我这个系列的来龙去脉。如果大家觉得本篇文章不水的话希望帮忙点赞收藏加关注,你们的鼓舞是我继续更新的动力。 我为什么会写这个系列呢? 首先肯定是因为我本身就是一名从业通信者,想着更加了解自…

高性能 Web 服务器:让网页瞬间绽放的魔法引擎(中)

目录 一.Nginx版本和安装方式:源码编译安装 1.验证版本及编译参数 2.使用安装完成的二进制文件nginx 3.Nginx 启动文件 二.平滑升级和回滚 三.全局配置 实现 nginx 的高并发配置 四.核心配置:新建一个 PC web 站点 五.核心配置:location的详细使用…

vscode 远程控制ssh操作步骤

1.下载拓展Remote - SSH 打开Visual Studio Code,进入拓展市场(CtrlShiftX),下载拓展Remote - SSH 2.选择远程(隧道/SSH)类别 点击远程资源管理器选项卡,并选择远程(隧道/SSH)类别 4.在弹出的选择配置文件中,点击第一个 5. 连接到…

基于PHP网上投票系统---附源码121500

摘 要 随着全球Internet的迅猛发展和计算机应用的普及,特别是近几年无线网络的广阔覆盖以及无线终端设备的爆炸式增长,使得人们能够随时随地的访问网络,以获取最新信息、参与网络活动、和他人在线互动。为了能及时地了解民情民意,…

深度学习基础—学习率衰减与局部最优问题

1.学习率衰减 下图中,蓝色的线是min-batch梯度下降法过程中较大学习率的的优化路径,绿线是较小学习率的优化路径。 如果使用min-batch梯度下降法,在模型的学习过程中,会有很多噪声,在靠近最小值的时候,由于…

考试:数据库系统(02)

关系代数 ◆并:结果是两张表中所有记录数合并,相同记录只显示一次。 ◆交:结果是两张表中相同的记录。 ◆差:S1-S2, 结果是S1表中有而S2表中没有的那些记录。 ◆笛卡尔积:S1*S2,产生的结果包括S1和S2的所有属性列&…

Redis7基础篇(二)

目录 持化双雄 RDB 案例演示 优势 劣势 AOF 案例演示 正常恢复 异常恢复 优点 缺点​编辑 aof重写机制 ​编辑​编辑重写的原理​编辑 小总结 rdb和aof的混合持久化 纯缓存模式 redis的持久化最终还是靠硬盘 持化双雄 redis提供了一rdb aof 不持久化 rdbaof的…