FFmpeg源代码简单分析-架构图-解码

参考链接

  • FFmpeg源代码结构图 - 解码_雷霄骅的博客-CSDN博客_ffmpeg雷霄骅

函数背景色

  • 函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用:
    • 粉红色背景函数:FFmpeg的API函数。
    • 白色背景的函数:FFmpeg的内部函数。
    • 黄色背景的函数:URLProtocol结构体中的函数,包含处理协议(Protocol)的功能。
    • 绿色背景的函数:AVInputFormat结构体中的函数,包含处理封装格式(Format)的功能。
    • 蓝色背景的函数:AVCodec结构体中的函数,包含了编解码器(Codec)的功能。
  • PS:URLProtocol,AVInputFormat,AVCodec在FFmpeg开始运行并且注册完组件之后,都会分别被连接成一个个的链表。因此实际上是有很多的URLProtocol,AVInputFormat,AVCodec的。
  • 图中画出了解码一个输入协议是“文件”(其实就是打开一个文件。“文件”也被当做是一种广义的协议),封装格式为FLV,视频编码格式是H.264的数据的函数调用关系。 

区域

  • 整个架构图可以分为以下几个区域:
  • 左边区域——架构函数区域:这些函数并不针对某一特定的视频格式,通用架构,通用流程
  • 右上方黄色区域——协议处理函数区域:不同的协议(RTP,RTMP,FILE)会调用不同的协议处理函数。
  • 右边中间绿色区域——封装格式处理函数区域:不同的封装格式(MKV,FLV,MPEGTS,AVI)会调用不同的封装格式处理函数。
  • 右边下方蓝色区域——编解码函数区域:不同的编码标准(HEVC,H.264,MPEG2)会调用不同的编解码函数。

箭头线

  • 为了把调用关系表示的更明显,图中的箭头线也使用了不同的颜色:
  • 黑色箭头线:标志了函数之间的调用关系。
  • 红色的箭头线:标志了解码的流程。
  • 其他颜色的箭头线:标志了函数之间的调用关系。其中:
    • 调用URLProtocol结构体中的函数用黄色箭头线标识;
    • 调用AVInputFormat结构体中的函数用绿色箭头线标识;
    • 调用AVCodec结构体中的函数用蓝色箭头线标识。

函数所在的文件

  • 每个函数旁边标识了它所在的文件的路径。
  • 此外,还有一点需要注意的是,一些API函数内部也调用了另一些API函数。也就是说,API函数并不一定全部都调用FFmpeg的内部函数,他也有可能调用其他的API函数。
    • 例如从图中可以看出来,avformat_close_input()调用了avformat_free_context()和avio_close()。这些在内部代码中被调用的API函数也标记为粉红色。

现在的执行流程

  • FFmpeg在avcodec.register_all被弃用后,新的流程_弥彦已死的博客-CSDN博客
  • 从学龄前开始解读FFMPEG代码 之 avcodec_register_all函数_zzyincsdn的博客-CSDN博客

模块介绍 

右上区域(URLProtocol协议处理函数)

  • URLProtocol结构体包含如下协议处理函数指针:
    • url_open():打开
    • url_read():读取
    • url_write():写入
    • url_seek():调整进度
    • url_close():关闭
  • 结构体代码
typedef struct URLProtocol {const char *name;int     (*url_open)( URLContext *h, const char *url, int flags);/*** This callback is to be used by protocols which open further nested* protocols. options are then to be passed to ffurl_open_whitelist()* or ffurl_connect() for those nested protocols.*/int     (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);int     (*url_accept)(URLContext *s, URLContext **c);int     (*url_handshake)(URLContext *c);/*** Read data from the protocol.* If data is immediately available (even less than size), EOF is* reached or an error occurs (including EINTR), return immediately.* Otherwise:* In non-blocking mode, return AVERROR(EAGAIN) immediately.* In blocking mode, wait for data/EOF/error with a short timeout (0.1s),* and return AVERROR(EAGAIN) on timeout.* Checking interrupt_callback, looping on EINTR and EAGAIN and until* enough data has been read is left to the calling function; see* retry_transfer_wrapper in avio.c.*/int     (*url_read)( URLContext *h, unsigned char *buf, int size);int     (*url_write)(URLContext *h, const unsigned char *buf, int size);int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);int     (*url_close)(URLContext *h);int (*url_read_pause)(URLContext *h, int pause);int64_t (*url_read_seek)(URLContext *h, int stream_index,int64_t timestamp, int flags);int (*url_get_file_handle)(URLContext *h);int (*url_get_multi_file_handle)(URLContext *h, int **handles,int *numhandles);int (*url_get_short_seek)(URLContext *h);int (*url_shutdown)(URLContext *h, int flags);const AVClass *priv_data_class;int priv_data_size;int flags;int (*url_check)(URLContext *h, int mask);int (*url_open_dir)(URLContext *h);int (*url_read_dir)(URLContext *h, AVIODirEntry **next);int (*url_close_dir)(URLContext *h);int (*url_delete)(URLContext *h);int (*url_move)(URLContext *h_src, URLContext *h_dst);const char *default_whitelist;
} URLProtocol;

 注意事项:

  • 【例子】不同的协议对应着上述接口有不同的实现函数,举几个例子:
  • File协议(即文件)对应的URLProtocol结构体ff_file_protocol:
  • ff_file_protocol结构体的文件在<libavformat/file.c>
    • url_open() -> file_open() -> open()
    • url_read() -> file_read() -> read()
    • url_write() -> file_write() -> write()
    • url_seek() -> file_seek() -> lseek()
    • url_close() -> file_close() -> close()
const URLProtocol ff_file_protocol = {.name                = "file",.url_open            = file_open,.url_read            = file_read,.url_write           = file_write,.url_seek            = file_seek,.url_close           = file_close,.url_get_file_handle = file_get_handle,.url_check           = file_check,.url_delete          = file_delete,.url_move            = file_move,.priv_data_size      = sizeof(FileContext),.priv_data_class     = &file_class,.url_open_dir        = file_open_dir,.url_read_dir        = file_read_dir,.url_close_dir       = file_close_dir,.default_whitelist   = "file,crypto,data"
};
  • RTMP协议(libRTMP)对应的URLProtocol结构体ff_librtmp_protocol:
  • ff_librtmp_protocol结构体的文件在<libavformat/protocol>
    • url_open() -> rtmp_open() -> RTMP_Init(), RTMP_SetupURL(), RTMP_Connect(), RTMP_ConnectStream()
    • url_read() -> rtmp_read() -> RTMP_Read()
    • url_write() -> rtmp_write() -> RTMP_Write()
    • url_seek() -> rtmp_read_seek() -> RTMP_SendSeek()
    • url_close() -> rtmp_close() -> RTMP_Close()
RTMP_CLASS(rtmp)
const URLProtocol ff_librtmp_protocol = {.name                = "rtmp",.url_open            = rtmp_open,.url_read            = rtmp_read,.url_write           = rtmp_write,.url_close           = rtmp_close,.url_read_pause      = rtmp_read_pause,.url_read_seek       = rtmp_read_seek,.url_get_file_handle = rtmp_get_file_handle,.priv_data_size      = sizeof(LibRTMPContext),.priv_data_class     = &librtmp_class,.flags               = URL_PROTOCOL_FLAG_NETWORK,
};
  • UDP协议对应的URLProtocol结构体ff_udp_protocol:
  • ff_udp_protocol结构体位于<libavformat/udp.c>
    • url_open() -> udp_open()
    • url_read() -> udp_read()
    • url_write() -> udp_write()
    • url_seek() -> udp_close()
    • url_close() -> udp_close()
const URLProtocol ff_udp_protocol = {.name                = "udp",.url_open            = udp_open,.url_read            = udp_read,.url_write           = udp_write,.url_close           = udp_close,.url_get_file_handle = udp_get_file_handle,.priv_data_size      = sizeof(UDPContext),.priv_data_class     = &udp_class,.flags               = URL_PROTOCOL_FLAG_NETWORK,
};

右中区域(AVInputFormat封装格式处理函数)

  • AVInputFormat包含如下封装格式处理函数指针:
    • read_probe():检查格式
    • read_header():读取文件头
    • read_packet():读取一帧数据
    • read_seek():调整进度
    • read_close():关闭

 注意事项:

  • 【例子】不同的封装格式对应着上述接口有不同的实现函数,举几个例子:
  • FLV封装格式对应的AVInputFormat结构体ff_flv_demuxer:
    • read_probe() -> flv_probe() –> probe()
    • read_header() -> flv_read_header() -> create_stream() -> avformat_new_stream()
    • read_packet() -> flv_read_packet()
    • read_seek() -> flv_read_seek()
    • read_close() -> flv_read_close()
  • FFmpeg: libavformat/flvdec.c File Reference
= {.name           = "flv",.long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),.priv_data_size = sizeof(FLVContext),.read_probe     = flv_probe,.read_header    = flv_read_header,.read_packet    = flv_read_packet,.read_seek      = flv_read_seek,.read_close     = flv_read_close,.extensions     = "flv",.priv_class     = &flv_class,
}
  • MKV封装格式对应的AVInputFormat结构体ff_matroska_demuxer:
    • read_probe() -> matroska_probe()
    • read_header() -> matroska_read_header()
    • read_packet() -> matroska_read_packet()
    • read_seek() -> matroska_read_seek()
    • read_close() -> matroska_read_close()
  • 参考链接:FFmpeg: libavformat/matroskadec.c File Reference
= {.name           = "matroska,webm",.long_name      = NULL_IF_CONFIG_SMALL("Matroska / WebM"),.extensions     = "mkv,mk3d,mka,mks",.priv_data_size = sizeof(MatroskaDemuxContext),.read_probe     = matroska_probe,.read_header    = matroska_read_header,.read_packet    = matroska_read_packet,.read_close     = matroska_read_close,.read_seek      = matroska_read_seek,.mime_type      = "audio/webm,audio/x-matroska,video/webm,video/x-matroska"
}
  • MPEG2TS封装格式对应的AVInputFormat结构体ff_mpegts_demuxer:
    • read_probe() -> mpegts_probe()
    • read_header() -> mpegts_read_header()
    • read_packet() -> mpegts_read_packet() 
    • read_close() -> mpegts_read_close()
  • 参考链接:FFmpeg: libavformat/mpegts.c File Reference
= {.name           = "mpegts",.long_name      = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),.priv_data_size = sizeof(MpegTSContext),.read_probe     = mpegts_probe,.read_header    = mpegts_read_header,.read_packet    = mpegts_read_packet,.read_close     = mpegts_read_close,.read_timestamp = mpegts_get_dts,.flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,.priv_class     = &mpegts_class,
}
  • AVI封装格式对应的AVInputFormat结构体ff_avi_demuxer:
    • read_probe() -> avi_probe()
    • read_header() -> avi_read_header()
    • read_packet() -> avi_read_packet()
    • read_seek() -> avi_read_seek()
    • read_close() -> avi_read_close()
  • 参考链接:FFmpeg: libavformat/avidec.c File Reference
= {.name           = "avi",.long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),.priv_data_size = sizeof(AVIContext),.extensions     = "avi",.read_probe     = avi_probe,.read_header    = avi_read_header,.read_packet    = avi_read_packet,.read_close     = avi_read_close,.read_seek      = avi_read_seek,.priv_class = &demuxer_class,
}

右下区域(AVCodec编解码函数)

  • AVCodec包含如下编解码函数指针:
    • init():初始化
    • decode():解码一帧数据
    • close():关闭
  • 参考链接:FFmpeg: AVCodec Struct Reference
  • 上述参考链接里面包含的结构体包含上述编解码函数指针
  • 但是新版本好像没有了
typedef struct AVCodec {/*** Name of the codec implementation.* The name is globally unique among encoders and among decoders (but an* encoder and a decoder can share the same name).* This is the primary way to find a codec from the user perspective.*/const char *name;/*** Descriptive name for the codec, meant to be more human readable than name.* You should use the NULL_IF_CONFIG_SMALL() macro to define it.*/const char *long_name;enum AVMediaType type;enum AVCodecID id;/*** Codec capabilities.* see AV_CODEC_CAP_**/int capabilities;uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoderconst AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}const enum AVPixelFormat *pix_fmts;     ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
#if FF_API_OLD_CHANNEL_LAYOUT/*** @deprecated use ch_layouts instead*/attribute_deprecatedconst uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
#endifconst AVClass *priv_class;              ///< AVClass for the private contextconst AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}/*** Group name of the codec implementation.* This is a short symbolic name of the wrapper backing this codec. A* wrapper uses some kind of external implementation for the codec, such* as an external library, or a codec implementation provided by the OS or* the hardware.* If this field is NULL, this is a builtin, libavcodec native codec.* If non-NULL, this will be the suffix in AVCodec.name in most cases* (usually AVCodec.name will be of the form "<codec_name>_<wrapper_name>").*/const char *wrapper_name;/*** Array of supported channel layouts, terminated with a zeroed layout.*/const AVChannelLayout *ch_layouts;
} AVCodec;

 注意事项:

  • 【例子】不同的编解码器对应着上述接口有不同的实现函数,举几个例子:
  • HEVC解码对应的AVCodec结构体ff_hevc_decoder:
    • init() -> hevc_decode_init()
    • decode() -> hevc_decode_frame() -> decode_nal_units()
    • close() -> hevc_decode_free()
  • 参考链接:FFmpeg: libavcodec/hevc.c File Reference
= {.name                  = "hevc",.long_name             = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),.type                  = AVMEDIA_TYPE_VIDEO,.id                    = AV_CODEC_ID_HEVC,.priv_data_size        = sizeof(HEVCContext),.priv_class            = &hevc_decoder_class,.init                  = hevc_decode_init,.close                 = hevc_decode_free,.decode                = ,.flush                 = hevc_decode_flush,.update_thread_context = hevc_update_thread_context,.init_thread_copy      = hevc_init_thread_copy,.capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,.profiles              = NULL_IF_CONFIG_SMALL(profiles),
}
  • H.264解码对应的AVCodec结构体ff_h264_decoder:
    • init() -> ff_h264_decode_init()
    • decode() -> h264_decode_frame() -> decode_nal_units()
    • close() -> h264_decode_end()
  • 参考链接:FFmpeg: libavcodec/h264.c File Reference
= {.name                  = "h264",.long_name             = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),.type                  = AVMEDIA_TYPE_VIDEO,.id                    = AV_CODEC_ID_H264,.priv_data_size        = sizeof(H264Context),.init                  = ff_h264_decode_init,.close                 = h264_decode_end,.decode                = h264_decode_frame,.capabilities          =  AV_CODEC_CAP_DR1 |AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |AV_CODEC_CAP_FRAME_THREADS,.flush                 = flush_dpb,.init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),.profiles              = NULL_IF_CONFIG_SMALL(profiles),.priv_class            = &h264_class,
}
  • VP8解码(libVPX)对应的AVCodec结构体ff_libvpx_vp8_decoder:
    • init() -> vpx_init() -> vpx_codec_dec_init()
    • decode() -> vp8_decode() -> vpx_codec_decode(), vpx_codec_get_frame()
    • close() -> vp8_free() -> vpx_codec_destroy()
  • 版本差异
  • 参考链接:FFmpeg: libavcodec/libvpxdec.c Source File
AVCodec ff_libvpx_vp8_decoder = {.name           = "libvpx",.type           = AVMEDIA_TYPE_VIDEO,.id             = AV_CODEC_ID_VP8,.priv_data_size = sizeof(VP8Context),.init           = vp8_init,.close          = vp8_free,.decode         = vp8_decode,.capabilities   = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1,.long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
};
  • MPEG2解码对应的AVCodec结构体ff_mpeg2video_decoder:
    • init() -> mpeg_decode_init()
    • decode() -> mpeg_decode_frame()
    • close() -> mpeg_decode_end()
  • 参考链接:FFmpeg: libavcodec/mpeg12dec.c File Reference
= {.name           = "mpeg2video",.long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 video"),.type           = AVMEDIA_TYPE_VIDEO,.id             = AV_CODEC_ID_MPEG2VIDEO,.priv_data_size = sizeof(Mpeg1Context),.init           = mpeg_decode_init,.close          = mpeg_decode_end,.decode         = mpeg_decode_frame,.capabilities   = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |AV_CODEC_CAP_SLICE_THREADS,.flush          = flush,.max_lowres     = 3,.profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
}

 注意事项

  • FFmpeg (libav*) 开发踩过的坑 - 哔哩哔哩

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

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

相关文章

JUnit单元测试笔记

#01 JUnit简介 1.在项目工程中的Library,add 一个JUnit的Jar包&#xff0c;按需要添加JUnit 3 或 JUnit 4&#xff08;分为被测试类与测试类较佳&#xff09;。 2.单元测试是由程序员完成的。 3.Java 5 之前的版本只能 用JUnit 4前的版本&#xff08;因为JUnit 4用到Java 5的…

jqery获取每个月天数_三年级《年、月、日》单元重要知识点整理汇总,以及难点题型解析...

昨天给大家分享了《计算经过的时间》问题&#xff0c;今天给大家分享的是《年、月、日》单元中重要的几个知识点&#xff0c;以及难点题型解析。知识点1 感知年、月、日一、结合生活实际&#xff0c;看看下面事情需要经过多少时间。跑完100米大约需要经过十几(秒)。2.打一场篮球…

FFmpeg源代码简单分析-架构图-编码

参考链接 FFmpeg源代码结构图 - 编码_雷霄骅的博客-CSDN博客_ffmpeg 源码函数背景色 函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用&#xff1a; 粉红色背景函数&#xff1a;FFmpeg的API函数。白色背景的函数&#xff1a;FFmpeg的内部函数。黄色背景的…

为革命,保护视力——为Eclipse更换暗黑皮肤及编辑页面的字体颜色主题

1.在Eclipse中的菜单栏的Help -> Eclipse Market 的 Search栏中输入 Eclipse Moonrise UI Theme &#xff0c;之后自己执生啦&#xff08;确保上网配置正确&#xff09;。 2.与上面操作类似&#xff0c;输入 Eclipse Color Theme&#xff0c;选择安装。 3.选择菜单栏的Win…

FFmpeg源代码简单分析-通用- 内存的分配和释放(av_malloc()、av_free()等)

参考链接 FFmpeg源代码简单分析&#xff1a;内存的分配和释放&#xff08;av_malloc()、av_free()等&#xff09;_雷霄骅的博客-CSDN博客_av_malloc 内容介绍 内存操作的常见函数位于libavutil\mem.c中本文记录最常使用的几个函数&#xff1a; av_malloc()av_realloc()av_mal…

FFmpeg源代码简单分析-通用-结构体分析-AVFormatContext

参考链接 FFMPEG结构体分析&#xff1a;AVFormatContext_雷霄骅的博客-CSDN博客_avformatcontext AVFormatContext AVFormatContext是包含码流参数较多的结构体结构体的定义位于libavformat/avformat.h/*** Format I/O context.//格式化 I/O 上下文* New fields can be added…

plsql如何显示表结构图_【论文攻略】排版技巧——如何用 Word 编辑参考文献

每个需要写毕业论文的朋友都会发现&#xff0c;修改文献是一件非常痛苦的事情&#xff0c;虽然现在也有很多软件可以编排参考文献&#xff0c;其实 word 本身就可以。采用合适的编辑方法会方便地做到整齐,规范, 自动排序和交叉引用。 1. 以尾注的方式插入第一个参考文献将光标定…

FFmpeg源代码简单分析-通用-结构体分析-AVCodecContext

参考链接 FFMPEG结构体分析&#xff1a;AVCodecContext_雷霄骅的博客-CSDN博客_avcodeccontext AVCodecContext AVCodecContext是包含变量较多的结构体&#xff08;感觉差不多是变量最多的结构体&#xff09;结构体的定义位于avcodec.h关键的变量如下所示&#xff08;仅仅考虑…

Hello OpenGL——OpenGL在Visual c++6.0安装和配置

1、下载并安装glut库opengl的glut库 GLUT不是OpenGL所必须的&#xff0c;但它会给我们的学习带来一定的方便&#xff0c;推荐安装。 Windows环境下的GLUT下载地址&#xff1a;&#xff08;大小约为150k&#xff09; http://www.opengl.org/resources/libraries/glut/glutdlls37…

FFmpeg源代码简单分析-通用-结构体分析-AVIOContext

参考链接 FFMPEG结构体分析&#xff1a;AVIOContext_雷霄骅的博客-CSDN博客_aviocontext AVIOContext AVIOContext是FFMPEG管理输入输出数据的结构体结构体的定义位于位于avio.h关键的变量如下所示 unsigned char *buffer&#xff1a;缓存开始位置int buffer_size&#xff1…

初闻动态规划

前言 本文以一道常见的算法面试题开篇&#xff0c;引入动态规划的基础概念&#xff0c; 介绍其思考过程。 正文 一、常见的一道算法面试题——上台阶 有一个楼梯总共n个台阶&#xff0c;只能往上走&#xff0c;每次只能上1个、2个台阶&#xff0c;总共有多少种走法。 解决…

FFmpeg源代码简单分析-通用-结构体分析-AVCodec

参考链接 FFMPEG结构体分析&#xff1a;AVCodec_雷霄骅的博客-CSDN博客_avcodec AVCodec AVCodec是存储编解码器信息的结构体结构体的定义位于avcodec.h文件中最主要的几个变量 const char *name&#xff1a;编解码器的名字&#xff0c;比较短const char *long_name&#xff…

SLF4J简介与使用(整合log4j)

SLF4J简介与使用(整合log4j) 一、概念 SLF4J的全称是Simple Logging Facade for Java&#xff0c;即简单日志门面。SLF4J并不是具体的日志框架&#xff0c;而是作为一个简单门面服务于各类日志框架&#xff0c;如java.util.logging, logback和log4j。 SLF4J提供了统一的记录…

multism中ui和uo应该怎么表示_王者荣耀:梦泪直播时谈到体验服大改动,表示装备的改动很关键...

王者荣耀的主播梦泪&#xff0c;大家都很熟了&#xff0c;也是一个很强的主播&#xff0c;他对于王者荣耀的理解&#xff0c;还是非常深刻的&#xff0c;而最近王者荣耀的体验服&#xff0c;进行了大改动&#xff0c;也是改变了很多的东西。对此&#xff0c;网友们也是非常的在…

怎么关闭或者卸载ivanti_电脑软件卸载不了怎么办,教您解决电脑软件无法卸载方法技巧...

我们在使用电脑的过程中&#xff0c;肯定会安装各种软件&#xff0c;但是一些软件在使用完之后就不会再使用了&#xff0c;但又无法卸载。下面由小编分享一下电脑安装的软件无法卸载解决方法&#xff0c;如果你在某卸载软件的时候出现无法卸载的情况&#xff0c;不妨通过以下方…

解决Github图片加载失败

问题描述 浏览自己Github某仓库的README.md内时&#xff0c;发现文档的图片始终加载不出&#xff0c;打开浏览器后台&#xff0c;冒出一片红&#xff0c;Failed to load resource: net::ERR_CONNECTION_RESET&#xff0c;如下图所示&#xff1a; 问题分析 可能造成这问题的原…

FFmpeg源代码简单分析-通用-结构体分析-关键结构体之间的关系

参考链接 FFMPEG中最关键的结构体之间的关系_雷霄骅的博客-CSDN博客_ffmpeg 结构体关系 最关键的结构体可以分成以下几类&#xff1a; 解协议&#xff08;http,rtsp,rtmp,mms&#xff09; AVIOContext&#xff0c;URLProtocol&#xff0c;URLContext主要存储视音频使用的协…

用Python下载文件

前提条件 需要事先安装requests模块&#xff1a; pip install requests 放码过来 import requestsurl XXX #文件下载来源URL filename #下载到本地后新文件名 r requests.get(url) with open(filename, "wb") as code:code.write(r.content)实战演习 从目标…

FFmpeg源代码简单分析-通用-常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

参考链接 FFmpeg源代码简单分析&#xff1a;常见结构体的初始化和销毁&#xff08;AVFormatContext&#xff0c;AVFrame等&#xff09;_雷霄骅的博客-CSDN博客 结构体 AVFormatContext&#xff1a;统领全局的基本结构体。主要用于处理封装格式&#xff08;FLV/MKV/RMVB等&…

FFmpeg源代码简单分析-通用-avio_open2()

参考链接 FFmpeg源代码简单分析&#xff1a;avio_open2()_雷霄骅的博客-CSDN博客_avio_open avio_open2() 该函数用于打开FFmpeg的输入输出文件avio_open2()的声明位于libavformat\avio.h文件中&#xff0c;如下所示。 /*** Create and initialize a AVIOContext for accessi…