VLC架构及流程分析

2023-05-16

注明:此文为转载。原文地址:https://jiya.io/archives/vlc_learn_2.html

由于本人之前由于在工作中需要对VLC进行二次开发。因此进行了相关工作的开发(由于工作原因、目前暂未接触相关开发)。在研究过程中,发现了此篇很好的文章。这篇文章也很好地验证和帮助了我当时的工作,因此转载于此。

0x00 前置信息

VLC是一个非常庞大的工程,我从它的架构及流程入手进行分析,涉及到一些很细的概念先搁置一边,日后详细分析。

0x01 源码结构(Android Java相关的暂未分析)

# build-android-arm-linux-androideabi/:第三方库。
# modules/:模块代码。
# modules/demux:      解复用模块代码。
# modules/codec:       解码模块相关代码。
# modules/access:    访问模块相关代码。
# 其他:未详细分析。
# src/: VLC架构核心代码。
# src/config/:           从命令行和配置文件加载配置,提供功能模块的读取和写入配置。
# src/control/:            提供动作控制功能,如播放/暂停,音量管理,全屏,日志等。
# src/extras/:             平台特殊性相关代码。
# src/modules/:          模块管理。
# src/network/:           提供网络接口。
# src/posix/:               多线程相关。
# src/osd/:                 显示屏幕上的操作。
# src/interface/ :         提供代码中可以调用的接口中,如按键后硬件作出反应。
# src/playlist/:            管理播放功能,如停止,播放,下一首,随机播放等。
# src/text/:                 字符集。
# src/input/:               输入流相关代码。
# src/video_output/ :   初始化视频播放器,把从解码器获得的数据处理后播放。
# src/audio_output/ :   初始化音频混合器,把从解码器获得的数据处理后播放。
# src/stream_output/:  输出音频流和视频流到网络。
# src/test/:                  libvlc测试模块。
# src/misc/:                libvlc使用的其他部分功能,如线程系统,消息队列,CPU的检测,对象查找系统,或平台的特定代码。
# 其他:未详细分析。

0x02 基础概念

对于一个视频的播放,播放器的执行步骤大致如下:

  1. 读取原始数据
  2. 解复用
  3. 解码
  4. 显示

VLC在包含以上概念的基础上,又抽象出几个其他概念,先列出VLC中抽象出来的重要概念:

  1. playlist: playlist表示播放列表,VLC在启动后,即创建一个playlist thread,用户输入后,动态创建input。
  2. input: input表示输入,当用户通过界面输入一个文件或者流地址时,input thread 被动态创建,该线程的生命周期直到本次播放结束。
  3. access: access表示访问,是VLC抽象的一个层,该层向下直接使用文件或网络IO接口,向上为stream层服务,提供IO接口。
  4. stream: stream表示流,是VLC抽象的一个层,该层向下直接使用access层提供的IO接口,向上为demux层服务,提供IO接口。
  5. demux: demux表示解复用,是视频技术中的概念,该层向下直接使用stream层提供的IO接口,数据出来后送es_out。
  6. es_out: es_out表示输出,是VLC抽象的一个层,该层获取demux后的数据,送decode解码。
  7. decode: decode表示解码,是视频技术中的概念,获取es_out出来的数据(通过一个fifo交互),解码后送output。
  8. output: output表示输出,获取从decode出来的数据,送readerer。
  9. readerer: readerer表示显示,获取从output出来的数据(通过一个fifo交互),然后显示。

下图显示了这些抽象的概念的关系,其中蓝色表示VLC抽象的概念。

0x04 架构综述

VLC的整体框架是设计成一套module的管理机制,将功能分类并抽象成modules。

VLC main: player的main。初始化libVLC 并加载用户界面。
libVLCcore:libvlc的核心,抽象出了一个libvlc_instance_t 对象,提供modules的装载/卸载机制。
modules: modules提供具体的功能,比如上面的access,demux,decode就是以一个模块的形式存在。
External libraries:外部开源库。

模块的加载方式:
首先模块先将自身注册到VLC中,代码片段如:

vlc_module_begin()
...
vlc_module_end()

然后在需要加载模块的时候,调用module_need接口,去找到合适的模块。找到合适的模块后,会执行注册中设置的回调方法,诸如Open*名字的方法。
同样自己可以实现模块,只需要按照VLC模块的标准即可。VLC中很多模块就是通过外部的开源库实现的。

vlc中模块大致分类:

0x05 流程分析

首先,给出流程图,参照该图,再继续下面的流程分析,绿色线表示打开VLC后的执行操作;黑色线表示用户输入一个视频后的执行操作;蓝色线从红色圈开始,表示开始播放输入流后的数据流向。

(1) main函数(vlc/bin/vlc.c)
  1. 参数信号处理相关,不详分析。
  2. 调用libvlc_new()初始化一个libvlc_instance_t实例。(libvlc_instance_t is opaque. It represents a libvlc instance)
    2.1 调用libvlc_InternalCreate创建一个libvlc_int_t。(This structure is a LibVLC instance, for use by libvlc core and plugins.)
    2.2 调用libvlc_InternalInit初始化libvlc_int_t实例。
    2.3 初始化libvlc_instance_t其他成员。
  3. 调用libvlc_set_exit_handler设置VLC退出时的回调函数。
  4. 调用libvlc_add_intf添加模块。
    4.1 获取playlist,如果为空,则调用playlist_Create创建一个playlist结构,并调用playlist_Activate创建新的playlist线程Thread(src/playlist/thread.c)。
    4.2 调用intf_Create创建一个默认的interface。
    4.2.1 调用vlc_custom_create创建一个vlc object(intf_thread_t)。
    4.2.2 注册一个添加interface的回调方法。
    4.2.3 调用module_need加载一个interface模块。
  5. 调用libvlc_playlist_play,如果播放列表不为空,并且被设置为自动播放,则播放播放列表内容。
  6. 信号处理相关,不详分析。
(2) 创建一个输入
  1. 初始化成功后,程序运行在playlist的线程Thread(src/playlist/thread.c)中,循环接收界面输入的请求。
  2. 当输入一个新的文件或者流地址,在PlaylistVAControl获得信号,并发送该信号。
  3. Thread接收到播放请求后,在LoopRequest中调用PlayItem方法。
    3.1 调用input_Create创建一个input结构,并初始化各种成员,其中包括调用input_EsOutNew创建p_es_out_display(es_out)。
    3.2 调用input_Start创建一个input线程Run(src/input/input.c)。
(3) 初始化输入

调用Run(src/input/input.c)中的Init方法,开始初始化。

  1. 调用input_EsOutTimeshiftNew新建一个50M的Timeshift(暂停缓存),包括创建并初始化p_es_out(es_out),与后续步骤9相关。
  2. 设置input的状态为OPENING_S。
  3. 调用InputSourceInit。
    3.1 调用input_SplitMRL分解输入uri。
    3.2 以stream形参为NULL调用demux_New加载"access_demux"模块。
    3.3 如果没有合适的"access_demux"模块,则调用access_New创建一个实际的access。
    3.3.1 调用vlc_custom_create创建access_t结构体。
    3.3.2 调用module_need加载合适的access模块。
    3.3.3 调用access模块的Open*方法,以avio模块为例。
    3.3.3.1 调用vlc_init_avformat初始化VLC即avformat环境。
    3.3.3.2 调用avio_open2打开该uri。
    3.3.3.3 设置access的IO方法指针。
    3.4 调用stream_AccessNew创建一个stream。
    3.4.1 根据模式(stream/block)设置steam层的IO方法指针。stream层的IO方法实际指向access层对应的IO方法指针。
    3.4.2 为stream层的缓冲申请并初始化内存。
    3.4.3 调用AStreamPrebufferStream执行一次读操作。
    3.5 调用stream_FilterChainNew,Add stream filters(源码描述)。
    3.6 调用demux_New创建一个demux。
    3.6.1 调用vlc_custom_create创建demux_t结构体。
    3.6.2 调用module_need加载合适的demux模块。
    3.6.3 调用demux模块的Open*方法,以avformat/demux模块为例。
    3.6.3.1 调用stream_Peek从stream层获取数据,用于分析输入的文件格式。
    3.6.3.2 调用av_probe_input_format分析输入的文件格式。
    3.6.3.3 设置demux_sys_t结构体部分变量的值。
    3.6.3.4 调用avformat_alloc_context分配AVFormatContext结构体。
    3.6.3.5 调用avio_alloc_context设置AVFormatContext结构体的AVIOContext类型成员pb,并设置read和seek方法指针。
    3.6.3.6 调用avformat_open_input打开一个输入,这里的input与VLC中的input不是一个概念,关于avformat_open_input的分析详见我的另一篇文章《avformat_open_input详细分析》链接地址。
    3.6.3.7 调用avformat_find_stream_info分析流信息,该方法通过读取数据初始化流以及流解码信息。
    3.6.3.8 根据分析的流信息,设置fmt变量,并调用es_out_Add。
    3.6.3.9 实际调用EsOutAdd(src/input/es_out.c),添加一个es_out,有几个流就做几次es_out_Add操作,比如该输入中有一个视频流和一个音频流,则作两次es_out_Add操作。
    3.6.3.10 nb_chapters相关未详细分析。
    3.7 设置record相关。
    3.8 调用demux_Control设置demux pts delay。
    3.9 调用demux_Control设置fps。
  4. 调用demux_Control获取输入的长度。
  5. 调用StartTitle显示标题。
  6. 调用LoadSubtitles加载字幕。
  7. 调用LoadSlaves,含义不详。
  8. 调用InitPrograms,设置es_out和decoder相关。
    8.1 调用UpdatePtsDelay计算正确的pts_delay值。
    8.2 sout相关可选,暂不分析。
    8.3 调用es_out_SetMode,设置es_out的mode为ES_OUT_MODE_AUTO。
    8.4 以DEMUX_SET_GROUP指令调用demux_Control,DEMUX_SET_GROUP/SET_ES only a hint for demuxer (mainly DVB) to allow not reading everything。
  9. 续8.3,实际调用EsOutControlLocked进入case ES_OUT_SET_MODE分支。
    9.1 设置es_out_sys_t 的b_active和i_mode。
    9.2 调用EsOutSelect方法,根据指定模块选择一个es_out。
    9.3 在EsOutSelect方法中进入ES_OUT_MODE_AUTO分支,进一步调用EsSelect方法,再进一步调用EsCreateDecoder方法创建decoder。
    9.3.1 调用input_DecoderNew创建一个新的decoder。
    9.3.2 如果需要缓存,调用input_DecoderStartWait发送信号,开始线程等待。
    9.3.3 调用EsOutDecoderChangeDelay设置decode delay。
  10. 续9.3.1进入decoder_New方法。
    10.1 调用CreateDecoder创建decoder配置结构体。
    10.1.1 调用vlc_custom_create创建一个vlc object(decoder_t)。
    10.1.2 新建decode fifo。
    10.1.3 调用module_need加载适配的解码模块。
    10.1.3.1 调用decode模块的OpenDecoder方法,以codec/avcodec模块为例。
    10.1.3.2 调用GetFfmpegCodec方法 determine codec type(源码描述)。
    10.1.3.3 调用vlc_init_avcodec方法初始化解码环境。
    10.1.3.4 调用avcodec_find_decoder设置AVCodec。
    10.1.3.5 调用avcodec_alloc_context3分配一个AVCodecContext。
    10.1.3.6 调用Init*Dec系列初始化解码环境。
    10.1.4 初始化decoder_t结构体其他成员。
    10.2 调用vlc_clone创建解码线程DecoderThread。
  11. 续10.1.3.5,以InitVideoDec为例。
    12.1 为decoder_sys_t结构分配内存。
    12.2 设置相关回调方法。
    12.3 设置解码线程类型。
    12.4 调用ffmpeg_InitCodec初始化extradata相关数据。
    12.5 调用OpenVideoCodec方法,设置解码的长宽及采用率,进一步调用avcodec_open2打开codec。
  12. 根据需要,设置线程优先级。
  13. 设置meta相关。
  14. 初始化完成,设置该input的状态为PLAYING_S。
(4) 播放输入

MainLoop(src/input/input.c)

  1. 调用MainLoopDemux访问demuxer去demux数据。
  2. 进一步调用在加载demux模块时设置的demux方法,同样以avformat/demux模块为例,实际调用Demux方法(module/demux/avformat/demux.c)。
    2.1 调用av_read_frame读取一帧数据。
    2.2 判断读取无误时,则为block_t结构分配内存,并将这一帧从AVPacket中拷贝至block_t结构中。
    2.3 如果该帧是I帧,则设置I帧标致位。
    2.4 时间戳处理相关,未深入分析。
    2.5 根据需要调用es_out_Control设置PCR,未深入分析。
    2.6 调用es_out_Send将这一帧数据发送给es_out。
    2.7 调用av_free_packet释放这一帧数据。
  3. 调用es_out_Send后,实际调用EsOutSend(src/input/es_out.c)方法。
    3.1 调用stats_Update更新相关状态,具体未详分析。
    3.2 设置预读相关,如果需要预读,并且到的数据的pts小于预读需要的时间,则设置BLOCK_FLAG_PREROLL标志位。
    3.3 检查sout mode,具体有sync 和async mode,异同未详细分析。
    3.4 如果设置record,将数据dup后送decoder。
    3.5 调用input_DecoderDecode将block_t的数据送至decode fifo中。
    3.5.1 判断控制速度线程等待相关信息,具体未详细分析。
    3.5.2 如果decode fifo超过最大长度,则清空重置decode fifo。
    3.5.3 调用block_FifoPut将该block_t的数据压入decode fifo,并通知读取线程。
    3.6 格式变化判断处理相关,未详细分析。
    3.7 字幕处理相关,未详细分析。
  4. 续3.5进入decode read thread,即DecoderThread(src/input/decoder.c)。
    4.1 调用block_FifoGet方法,从decode fifo中获取数据。
    4.2 基于某些条件,发送停止等待消息给其他线程,未详细分析。
    4.3 调用DecoderProcess方法开始decode a block。
    4.4 判断输入流的格式,调用不同的方法,这里以视频流为例,调用DecoderProcessVideo方法。
    4.5 packetizer相关为深入分析,在DecoderProcessVideo方法中进一步调用DecoderDecodeVideo方法。
  5. 续4.5调用pf_decode_video,这里以avcodec模块的decoder为例,即DecodeVideo(modules/codec/avcodec/video.c)方法,在该方法中,开始真正的解码。
    5.1 如果在Demux中获取的流信息中包含新的extradata,并且原来的extradata数据为空,则调用ffmpeg_InitCodec初始化codec,如果b_delayed_open为true,则调用OpenVideoCodec重新打开codec。
    5.2 调用av_init_packet初始化解码数据包。
    5.3 调用avcodec_decode_video2解码数据。
    5.4 调用av_free_packet释放内存。
    5.5 计算pts值,返回解码后的数据。
    5.6 如果opaque为空,则调用ffmpeg_NewPictBuf方法创建一个新的picture buffer。具体调用回调指针pf_vout_buffer_new指向的vout_new_buffer,进一步调用input_resource_RequestVout最终调用VoutCreate。
    5.6.1 调用vlc_custom_create创建一个vlc object(vout_thread_t)。
    5.6.2 调用spu_Create初始化sub picture unit。
    5.6.3 调用vlc_clone创建一个output线程Thread(src/video_output/video_output.c)。
    5.6.4 output线程循环调用vout_control_Pop,首次进入ThreadControl方法中,执行ThreadStart方向,创建picture fifo(p->decoder_fifo)。
  6. pf_decode_video返回后,解码后的数据保存在p_pic中,进一步调用DecoderPlayVideo方法,在该方法中调用vout_PutPicture将解码后的数据压入picture fifo中。
  7. 当picture fifo中有数据后,vout线程调用ThreadDisplayPicture中的ThreadDisplayPreparePicture方法。
    7.1 调用picture_fifo_Pop从picture fifo中获取解码后的数据。
    7.2 如果延迟太大,并且设置延迟丢帧,则丢掉该帧数据。
  8. 调用ThreadDisplayRenderPicture显示图像。
0x06 总结

对VLC的流程分析,主要通过跟踪数据流向的方式展开。对于最后显示部分的分析还不足,另外很多细节尚未深入。

参考:

  1. http://blog.csdn.net/tx3344/article/details/8517062
  2. http://my.oschina.net/xiaot99/blog/197555
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VLC架构及流程分析 的相关文章

  • 在Windows下编译VLC并实现播放视频

    在Windows下编译VLC并实现播放视频 一 编译Win版的VLC真麻烦 二 获取VLC的SDK 1 下载VLC播放器 2 库文件 3 头文件 三 调用VLC实现播放视频 1 拷贝头文件和库文件 2 修改pro文件 3 封装播放器类VLC
  • 如何在 Ubuntu 20.04 上安装 VLC 媒体播放器

    VLC 是最流行的开源多媒体播放器之一 它是跨平台的 几乎可以播放所有多媒体文件以及 DVD 音频 CD 和不同的流媒体协议 本文介绍如何在 Ubuntu 20 04 上安装 VLC 媒体播放器 VLC 可以通过 Snapcraft 商店作
  • 基于VLC实现RTSP推流桌面(共享桌面)

    基于VLC实现RTSP推流桌面 共享桌面 一 添加VLC头文件和库文件 二 封装RTSPServer推流类 三 测试代码 不清楚推流大概原理的小伙伴 参考 设置VLC播放器进行RTSP推流桌面 共享桌面 这里以VLC 2 2 6版本为例 因
  • C#编写的基于VLC的播放器

    首先看一下最终的程序效果 实现的功能 1 打开播放的音视频文件 1 菜单栏 文件 gt 打开 2 工具栏 下面 打开 3 播放器右键 gt 打开 2 暂停 继续播放 停止音视频文件 3 进度条和右下角文本框显示播放进度 4 拖动进度条对视频
  • VLC Activex控件(VideoLAN.VLCPlugin.1 VideoLAN.VLCPlugin.2)的所有方法 属性及使用 在一个老外的网站上找到的...

    无意中在老外的网站上发现了关于VideoLAN VLCPlugin 1和VideoLAN VLCPlugin 2所有方法和属性 公布出来 以免大家浪费时间去寻找 注意你使用的VLC的版本 If you open a link to a vi
  • Windows下Python加载VLC的方法

    从网上看到一篇文章 Python 流媒体播放器 基于VLC 其中提到windows下开发VLC需要首先安装VLC 否则就需要设置环境变量PYTHON VLC MODULE PATH 但是我尝试了一下 没有成功 但是 这篇文章给了我一个思路
  • 如何在 Ubuntu 18.04 上安装 VLC 媒体播放器

    VLC 是最流行的开源多媒体播放器之一 它是跨平台的 几乎可以播放所有多媒体文件以及 DVD 音频 CD 和不同的流媒体协议 本教程介绍如何在 Ubuntu 18 04 上安装 VLC 媒体播放器 相同的说明适用于 Ubuntu 16 04
  • vlc mac python绑定没有视频输出

    我正在使用 vlc python 绑定来播放视频 然后我得到了这些错误 0x3d0c58 main window error corrupt module Applications VLC app Contents MacOS plugin
  • libvlc 流屏幕的一部分

    我想使用 vlc 库流式传输屏幕的一部分 我写了一个小例子 include
  • 使用VLC的虚拟界面时如何防止显示控制台

    我正在尝试从 Node js 服务器脚本以 虚拟 模式启动 VLC 但是使用child process spawn vlc I dummy 使用 Windows 时 为 VLC 的输出生成一个新的控制台窗口 有没有办法防止这种情况发生并强制
  • 如何在 C# 中通过 VLC api 流式传输视频

    我正在从事视频广播的小型家庭项目 我找到了一些例子Example http csharpmagics blogspot com 但它不起作用 因为需要旧版本的库0 8 6 所以我找到了它 但是当我尝试从 API 获取组件时 我对非托管代码有
  • 如何计算音频流中每个数据包的 RTP 时间戳

    我阅读了 RTP 规范 但似乎无法理解 RTP 数据包时间戳 我尝试在我的服务器中以不同的方式实现它 但我无法让玩家正确播放它 我在这里的 错误 行为是 我使用 VLC 播放器播放 RTSP url 到我的服务器 我发现玩家的日志说 缓冲太
  • 在Java中启动VLC并通过rc接口连接到它

    我已经看过这个帖子了 但我仍然遇到一个问题 在java中启动vlc播放器 https stackoverflow com questions 1731299 starting vlc player in java看来 VLC 的 Java
  • libVLC 函数 media_player_new() 抛出分段错误

    media player new 抛出分段错误 import vlc ins vlc Instance player ins media player new 这是它崩溃的地方 Thread 0 Crashed Dispatch queue
  • 使用 VLC 托管无限视频循环流

    我想通过 WIFI 网络从带有 VLC 播放器的电脑向智能手机提供视频流以进行回归测试 视频在智能手机上播放完毕后应自动重新开始 我目前使用 rtsp 作为协议和循环选项 但这不是强制性的 问题是 每次视频重新启动时 都需要进行新的 rts
  • 使用 VLC 将文件流式传输为 RTSP

    我需要创建一个可以将 mp3 文件流式传输到另一个设备的服务器 我打算使用 VLC 我查看了 VLC 文档 并对执行此操作的前进方向感到困惑 我找到了这个链接 http www videolan org doc streaming howt
  • 如何使用 VLC 以 ​​http 方式将视频流式传输到其他计算机 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想使用以下方式将视频从我的计算机流式传输到另一台计算机http in vlc 我已从此处阅读了如何进行视频流传输的步骤https wik
  • 如何在最新的 VLC 版本上通过命令行设置音量?

    我一直在尝试在 Ubuntu 上通过终端设置 VLC 2 2 1 中的音量 但没有成功 参数 volume不存在了 Warning option volume no longer exists 并且我在帮助中找不到任何包含 卷 的内容 文档
  • Android版VLC编译错误

    当我根据这个编译适用于Android的VLC时page https wiki videolan org AndroidCompile 在步骤 sh 编译 sh 我收到此错误 For an ARMv6 device without FPU e
  • VLC 和 ffmpeg 如何协同工作?

    我从源代码编译了VLC 它运行良好 当我执行 Vlc 时 vlc 运行 我还从源代码编译了 ffmpeg 它也运行良好 当我执行 ffmpeg i f toto flv mp3 vn acodec copy new toto mp3 时 会

随机推荐

  • matlab绘制垂线(x轴或y轴)

    使用line函数就可以绘制垂线 1 绘制垂直于x轴的垂线 line xvalue xvalue y1 y2 xff1b 比如绘制x 61 5 y取值为 0 10 xff1b line 5 5 0 10 2 绘制垂直于y轴的垂线 line x
  • ubuntu解决中文乱码

    1 查看当前系统使用的字符编码 locale LANG 61 en US LANGUAGE 61 en US LC CTYPE 61 34 en US 34 LC NUMERIC 61 34 en US 34 LC TIME 61 34 e
  • ROS 在工作空间中创建python程序

    ROS 在工作空间中创建python程序 基于ros xff0c 在工作空间catkin ws中创建pkg和python程序 xff0c 并进行编译使其可以用rosrun进行运行 xff0c 参考 xff1a 参考 默认前面已经创建了cat
  • 关于AD15铺铜的注意事项

    1 在铺好信号线和电源线后再考虑是否在铺地之前先手动连接地线 因为在铺地时有一个间距问题 xff0c 如果有限地线的间距太小 xff0c 那么在铺地时就会不成功 xff0c 导致墨迹个地没有被接进去 还有就是要考虑敷铜时的间距 xff0c
  • AD15 建立铺铜间距规则

    系统默认的普通间距就是系统的clearance 10mil xff0c 可是默认普通出来的话间距太小了 xff0c 于是乎可以建立一个普通规则 xff0c 但是要注意你所建立的铺铜规则优先级永远在默认优先级之前 xff08 比如你的poly
  • AD15 修改铺铜(去除自己不想要的铺铜区域)

    1 点击place gt polygon pour cutout 2 出现光标 xff0c 然后把你想要去除的那个区域选中 xff0c 如图一所示 xff0c 单击右键退出选择模式 3 双击没有被选中的区域 xff0c 软件提示重新铺铜 x
  • 串口缓冲区管理分析

    一 概述 xff1a 串口使用时一般包含两个缓冲区 xff0c 即发送缓冲区和接收缓冲区 发送数据时 xff0c 先将数据存在发送缓冲区 xff0c 然后通过串口发送 xff1b 接收数据时 xff0c 先将接收的数据存在接收缓冲区 xff
  • JLINK给STM32下载的两种模式--jtag & sw连线及配置

    jtag线就不说了 xff0c 将jlink的Vref GND TMS TCK分别接至SW接口 对于STM32F103RCT6来说 xff1a TMS PA12 xff0c TCK PA14 关于KEIL MDK中的设置如下图所示就可以了
  • 3.3V过压保护电路

    好久没写了 xff0c 今天就写一些工作中用到的一个电路 3 3V过压保护电路 通常一个电路中给单片机等对电压信息敏感的器件供电时都会小心翼翼 xff0c 严防前级降压电路出问题 xff0c 我就碰到过12V转5V的1117奔溃记过加在ST
  • eagle使用注意点

    使用eagle也有快一年时间了 xff0c 刚开始很不习惯 xff0c 后来习惯了也还可以 xff0c 这里我举出几个设计中经常出错的地方 xff1a 1 PCB翻转问题 xff1a 在翻转PCB文件时一定要打开torigin borigi
  • 自制pixhawk电脑不识别com口

    在原版pix上面进行改版很方便 xff0c 可以去除很多不必要的电路 笔者将电源管理芯片去除 xff0c 5V来源于变压器输出或者是连接电脑时的USB供电 xff0c 并将它们并联起来 xff0c 但是板子做回来焊接后发现问题如下 xff1
  • eagle pcb v8.2 便捷性大大提升

    eagle pcb在被Autodesk收购之前是7 x版本 xff0c 但是却有一些一直被吐槽的东西 xff0c 说实话这些东西确实增加了布线难度 xff0c 增加了布板时间 xff1a 1 real time DRC xff1a 在7 x
  • Ubuntu firefox 显示在运行无法打开,如何在终端关闭进程

    用top命令找不到firfox的进程 xff0c 查看某个用户运行的进程 xff1a ps u username grep eclipse 查看用户名为 xff1a username 的用户是否运行了eclipse 查看用户当前运行fire
  • 【万字详解】cJSON解析

    目录 1 通过README文件 xff0c 初步了解cJSON xff1a 1 1 头文件的开头和结尾 xff1a 1 2 头文件关于cJSON类型的宏定义 1 3 头文件中的extern 2 阅读并且分析cJSON源码 2 1 结构体st
  • VINS-mono 解析 新特征

    在17 12 29 xff0c VINS更新了代码加入了新的特征 xff0c 包括map merge 地图合并 pose graph reuse 位姿图重利用 online temporal calibration function 在线时
  • VINS-mono 位姿图 重利用测试

    在前一篇博文里介绍了VINS mono pose graph reuse功能的使用 xff0c 这里接着贴出一些延伸的测试 xff0c 并进行一些探讨 延伸测试 一般来说 xff0c 加载地图是进行非GPS定位必要的一步 这里根据新的VIN
  • 2022年全国大学生电子设计大赛省赛A题

    2022年全国大学生电子设计大赛省赛A题 交流电子负载 文章目录 2022年全国大学生电子设计大赛省赛A题 交流电子负载 前言一 总体思路二 模块设计1 半桥模块2 测量模块3 辅助电源模块 三 主电路搭建总结 前言 2022年全国大学生电
  • linux下使用shell发送http请求

    一 curl 1 get请求 curl命令默认下就是使用get方式发送http请求 curl www baidu com 2 post请求 使用 d参数 xff0c 形式如下 xff1a curl d 34 param1 61 value1
  • 网络摄像头 接口协议 ONVIF,PSIA,CGI,ISAPI

    ONVIF致力于通过全球性的开放接口标准来推进网络视频在安防市场的应用 xff0c 这一接口标准将确保不同厂商生产的网络视频产品具有互通性 2008年11月 xff0c 论坛正式发布了ONVIF第一版规范 ONVIF核心规范1 0 随着视频
  • VLC架构及流程分析

    注明 xff1a 此文为转载 原文地址 xff1a https jiya io archives vlc learn 2 html 由于本人之前由于在工作中需要对VLC进行二次开发 因此进行了相关工作的开发 xff08 由于工作原因 目前暂