<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NotionNext BLOG</title>
        <link>https://macrocborg.site/</link>
        <description>这是一个由NotionNext生成的站点</description>
        <lastBuildDate>Thu, 19 Oct 2023 07:50:42 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2023, macrocyborg</copyright>
        <item>
            <title><![CDATA[Win11+ VS2022编译 FFmpeg6.0 静态库]]></title>
            <link>https://macrocborg.site/article/07ab4b09-2b01-42c4-8faf-6c15c70b368a</link>
            <guid>https://macrocborg.site/article/07ab4b09-2b01-42c4-8faf-6c15c70b368a</guid>
            <pubDate>Thu, 17 Aug 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[本文使用当前最新版本的ffmpeg与编译环境编译一个可用的ffmpeg 静态/动态库]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-07ab4b092b0142c48faf6c15c70b368a"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-248fb60156ca454f88f10ce378189f90" data-id="248fb60156ca454f88f10ce378189f90"><span><div id="248fb60156ca454f88f10ce378189f90" class="notion-header-anchor"></div><a class="notion-hash-link" href="#248fb60156ca454f88f10ce378189f90" title="编译前言"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">编译前言</span></span></h2><div class="notion-text notion-block-c3ab787200324d2bb199d8fd77bee106">编译作为自己持有的稳定版本 用来练习</div><div class="notion-text notion-block-92d351e8d3ac4dc190050db5df1f13c1">网上有使用cygwin版本，在把ffmpeg作为静态库依赖的时候要添加iconv等其他的库，非常麻烦，有很长的打包链条，编译出来的库不能独自成军。</div><div class="notion-text notion-block-313201b680e64687af9e36b0e42bd840">网上其他的编译环境也太杂太乱了，目前有个开源项目致力解决ffmpeg编译的问题，暂时拿来用，如果这个项目不维护或者坏了，再考虑其他。</div><div class="notion-blank notion-block-ff80071fad48451789edf052ef233c2e"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-5aea1293661e4945bc683a30f1af898d" data-id="5aea1293661e4945bc683a30f1af898d"><span><div id="5aea1293661e4945bc683a30f1af898d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5aea1293661e4945bc683a30f1af898d" title="为什么编译ffmpeg？"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么编译ffmpeg？</span></span></h3><div class="notion-text notion-block-db33e9982e49441192f65076248e15fc">编译作为自己持有的稳定版本 用来练习ffmpeg的一些方法，音视频同步等操作。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-1b406694394d47eabdd715444297105d" data-id="1b406694394d47eabdd715444297105d"><span><div id="1b406694394d47eabdd715444297105d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1b406694394d47eabdd715444297105d" title="前期准备"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">前期准备</span></span></h3><div class="notion-text notion-block-58bd79654d874c8b91ef7881929efcd5">使用github 上 开源项目的解决方案编译
<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ShiftMediaProject/FFmpeg">ShiftMediaProject</a></div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-799936106c0c407bba7e7d4456d39b94" data-id="799936106c0c407bba7e7d4456d39b94"><span><div id="799936106c0c407bba7e7d4456d39b94" class="notion-header-anchor"></div><a class="notion-hash-link" href="#799936106c0c407bba7e7d4456d39b94" title="环境配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">环境配置</span></span></h4><div class="notion-text notion-block-ae98be13297e4a39b65560e739575084">先创建代码目录，作者建议的。</div><div class="notion-text notion-block-f44c7c4158fd47fda1353a2a48c76946">进入<code class="notion-inline-code">source</code>目录打开git bash 克隆代码</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f513c049835c46d29b440c277add2ebf"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="http://img.macrocyborg.site/notion/ffmpeg_01.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c6928ac8485040ee9f642f5c4c249b05">这里因为我已经git 拉到本地过了，所以报错，不影响。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-f96b8931b6d649598819b79c9340ecad" data-id="f96b8931b6d649598819b79c9340ecad"><span><div id="f96b8931b6d649598819b79c9340ecad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f96b8931b6d649598819b79c9340ecad" title="ffmpeg外部库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">ffmpeg外部库</span></span></h4><div class="notion-text notion-block-43b9833198804950a50fd97f61a9657d">代码拉取完毕后 ，如果一切顺利，<span class="notion-orange_background">/vs2022/source/FFmpeg/SMP</span>目录可以查看readme.txt，里面介绍了如何编译配置整个项目，包括外部库：x264、x264、vpx等，可以使用脚本下载，路径</div><div class="notion-text notion-block-d130a7ac37844b22841d56b3ed08ac66"><code class="notion-inline-code">vs2022\\source\\FFmpeg\\SMP\\project_get_dependencies.bat</code>,感兴趣可以看一下他这个bash脚本，它会按照脚本中配置的外部库名字</div><div class="notion-text notion-block-0def6b51872b4b01a68c85ec79dbc81a"><b>按顺序</b></div><div class="notion-text notion-block-583fbd0897f04589945b00b90a94bd57">拉取。如果万一下载失败 ，可以根据输出日志跟脚本内容排查问题，手动下载或者重新运行脚本。运行情况如下：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-45595ce2e1b84901b7b405663193a8ca"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="http://img.macrocyborg.site/notion/ffmpeg_02.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-13406e899c9a47a790568fd8dfab45ca">好了经过漫长的下载与数次执行<code class="notion-inline-code">./project_get_dependencies.bat</code></div><div class="notion-text notion-block-f57c5cc7ca7748a297231d55bc2dca71">,所有的库也都下下来了。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d4c302a1fb364ade8b199cecedb23e2d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="http://img.macrocyborg.site/notion/webrtc_202308161606196.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-c1cb4a8da5394adf86cfb3c985f98621" data-id="c1cb4a8da5394adf86cfb3c985f98621"><span><div id="c1cb4a8da5394adf86cfb3c985f98621" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c1cb4a8da5394adf86cfb3c985f98621" title="额外的编译选项-for渲染"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">额外的编译选项-for渲染</span></span></h4><div class="notion-text notion-block-2e91653ff31f4849b54c00807bfaa89c">根据<code class="notion-inline-code">readme.txt</code>先在<code class="notion-inline-code">/vs2022/msvc/</code>下创建<code class="notion-inline-code">include</code>目录，include里创建<code class="notion-inline-code">gl</code>、<code class="notion-inline-code">AMF</code>两个目录，用来放<code class="notion-inline-code">opengl</code>、<code class="notion-inline-code">nv-codec</code>、<code class="notion-inline-code">AMF</code>的头文件。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-0ce65fbc5b324830879b88c595c027ff"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="http://img.macrocyborg.site/notion/webrtc_202308161617777.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-c216f461a20243cd8b39d295d24de8e7" data-id="c216f461a20243cd8b39d295d24de8e7"><span><div id="c216f461a20243cd8b39d295d24de8e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c216f461a20243cd8b39d295d24de8e7" title="opengl (需要glext)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">opengl (需要glext)</span></span></h4><ul class="notion-list notion-list-disc notion-block-3b6fc053fbb84770852dc332348d708e"><li>a. <code class="notion-inline-code">OpenGL-Registry\\api\\GL\\</code> 里的<code class="notion-inline-code">glext.h</code>跟<code class="notion-inline-code">wglext.h</code>放入 <code class="notion-inline-code">/vs2022/msvc/include/gl/</code>中</li></ul><ul class="notion-list notion-list-disc notion-block-33190d46a6444339996c017994d986c3"><li>b. <code class="notion-inline-code">EGL-Registry\\api\\KHR</code> 将KHR整个文件夹放入<code class="notion-inline-code">/vs2022/msvc/include/</code>下</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-ce21edf6786c4f7f9f11d5bf996936dd" data-id="ce21edf6786c4f7f9f11d5bf996936dd"><span><div id="ce21edf6786c4f7f9f11d5bf996936dd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ce21edf6786c4f7f9f11d5bf996936dd" title="ffnvcodec (需要nv-codec-headers)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">ffnvcodec (需要nv-codec-headers)</span></span></h4><ul class="notion-list notion-list-disc notion-block-bab63008f4df4fdb812b722486d26347"><li>a.<code class="notion-inline-code"> nv-codec-headers\\include</code>里的ffnvcodec目录复制到<code class="notion-inline-code">/vs2022/msvc/include</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-6965209c3861426684404f91ec1c0554" data-id="6965209c3861426684404f91ec1c0554"><span><div id="6965209c3861426684404f91ec1c0554" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6965209c3861426684404f91ec1c0554" title="AMF sdk头文件"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AMF sdk头文件</span></span></h4><ul class="notion-list notion-list-disc notion-block-2b05782cbc8d4d3b8b0c773b08d01c41"><li>a. <code class="notion-inline-code">AMF\\amf\\public\\include</code>里的两个文件夹复制到<code class="notion-inline-code">/vs2022/msvc/include/AMF</code>中</li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-8a08938bc0f047e4bc48ed52edae54ea" data-id="8a08938bc0f047e4bc48ed52edae54ea"><span><div id="8a08938bc0f047e4bc48ed52edae54ea" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8a08938bc0f047e4bc48ed52edae54ea" title="编译工具链"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">编译工具链</span></span></h4><div class="notion-text notion-block-786caccc79d04ec588ef2f2d85d18fa6">配置 <code class="notion-inline-code">NASM</code>、<code class="notion-inline-code">YASM</code>,这两个是汇编的编译工具</div><div class="notion-text notion-block-8f83ead7790748af8ea97f32bf896b74">nasm</div><div class="notion-text notion-block-d2e3d03b79c0443c9be1dfaa02c7cbe5">yasm</div><div class="notion-text notion-block-844c2c657a16488d9ce711fa273a05f9">同样我们查看脚本可知它会根据不同VS的大版本去做适配安装，我们的是VS2022,vs17，如果有报错可以往这方面去排查。
执行安装</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e21cd3f6ac3342f79d404465f85cc5b6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="http://img.macrocyborg.site/notion/ffmpeg_20230817.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-341b2f5f0b3746e7a3e055145c4cbaa2" data-id="341b2f5f0b3746e7a3e055145c4cbaa2"><span><div id="341b2f5f0b3746e7a3e055145c4cbaa2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#341b2f5f0b3746e7a3e055145c4cbaa2" title="开始编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开始编译</span></span></h3><div class="notion-text notion-block-b3d8838641114d319671578a2578e955">到这一步，所有的准备工作基本完成，打开工程文件</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-6ed998234f384c4595240844767610e9"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/notion/ffmpeg20230817.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-6decab41f4ed458eac92cbe943ef74a0" data-id="6decab41f4ed458eac92cbe943ef74a0"><span><div id="6decab41f4ed458eac92cbe943ef74a0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6decab41f4ed458eac92cbe943ef74a0" title="step1. 选择编译类型 Debug/Release Dll/lib"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">step1. 选择编译类型 Debug/Release Dll/lib</span></span></h4><div class="notion-text notion-block-861bb41b6ea540869c0f6f5d397a2a07">这里我们先选择的Debug,因为只是练习用，需要调试什么的。
接下来就是直接生成了，生成时间稍微有点长，我这里10分钟左右，而且中间果不其然出现了错误。
让我们来分析一下：
在libavcodec 编译的过程中提示找不到好几个宏 都是NV_ENC_PARAMS打头的，我们找一下他的同类型,大概是这么一个枚举类型</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-0003417baf2e4a2eba672d5ab9168def"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171436.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-666070d9d2544d2ba5c653049f4d7f7e">，这里我们替换一下ffnvcode的版本，退回到5月份的版本，跟ffmpeg6r1保持一致</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e88a1c98bfe14e23a72d2ca91a64f996"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171438234.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-df77dd6d543d42cd8e4bfe3f8c9c7f2e">重新生成就能成功了。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-cc4717a971ce497faadc1048df4dd08f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171440847.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c58009997f5c46bc962dde0ed4027ae2">lib库在`/msvc/lib/x64下面，我们可以看到生成的各种lib库</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-6db9201e62594282ac8fdced14880776"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171442765.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-dab575b8d9f648a2a1103880c13303d0" data-id="dab575b8d9f648a2a1103880c13303d0"><span><div id="dab575b8d9f648a2a1103880c13303d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dab575b8d9f648a2a1103880c13303d0" title="step2. 打包SDK"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">step2. 打包SDK</span></span></h4><div class="notion-text notion-block-53f792c5151c4d90aad9c07e8bae80f1">把上述生成的include、lib打包带走，直接放到应用的项目下就可以直接用了</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3e590242bdcb47498165f4ae4bd40e22"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171446839.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-7f0757d6f7ad4bf2930434d0a502d992" data-id="7f0757d6f7ad4bf2930434d0a502d992"><span><div id="7f0757d6f7ad4bf2930434d0a502d992" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7f0757d6f7ad4bf2930434d0a502d992" title="验证"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">验证</span></span></h3><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1d6d41f4fe4a44198ceb25eceae67a65"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171514273.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-2d63a07923254578ab7674f6cabf98c6">结果如下，我们在这里输出了ffmpeg的编译配置，可以看到 其他的一些基础库都是<code class="notion-inline-code">enable</code>的状态，说明都编进去了，本次编译宣告成功。如需要在项目中使用到这些外部库诸如x265之类的，在项目中加上这些库的lib连接就可以。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d27e352d6de24e5482fa7f0f409c944e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column"><img src="https://img.macrocyborg.site/obsidian/ffmpeg_202308171513976.png" alt="notion image" loading="lazy" decoding="async"/></div></figure><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3d6de11ae2cd491db49f9229ca6aecb4" data-id="3d6de11ae2cd491db49f9229ca6aecb4"><span><div id="3d6de11ae2cd491db49f9229ca6aecb4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3d6de11ae2cd491db49f9229ca6aecb4" title="结尾"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">结尾</span></span></h3><div class="notion-text notion-block-1f40c15243654021b163b7fac1e7a66c">如果上述方式失效了，要回到手动编译配置的老路子，脏路子，也不用慌，相信经过这些配置编译的历程，作为老手，相信诸君也能轻松应对，处变不惊，将正确的东西放到正确的篮子里面。</div><div class="notion-text notion-block-f11e12d450dc45729076cc46e5e1677c">最后，感谢你的阅读，若能带来些许启发就更好了，与君共勉。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-e2a5a27127bd4ad6a6e770c08674b791" data-id="e2a5a27127bd4ad6a6e770c08674b791"><span><div id="e2a5a27127bd4ad6a6e770c08674b791" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e2a5a27127bd4ad6a6e770c08674b791" title="参考链接："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">参考链接：</span></span></h4><div class="notion-text notion-block-bb424b2351f8490799ff395d805733c3">1.<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/yao_hou/article/details/121581878?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4-121581878-blog-120804189.235%5Ev38%5Epc_relevant_sort_base1&amp;spm=1001.2101.3001.4242.3&amp;utm_relevant_index=7">CSDN令狐掌门</a></div><div class="notion-text notion-block-02e9701ddd494ff88f9d5cff260b7658">2.<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ShiftMediaProject">Shift Media Project</a></div><div class="notion-text notion-block-85d7a37ac5334ee3be6d298cdd607f15">3.<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://git.ffmpeg.org/gitweb/ffmpeg.git">FFMPEG官方git仓库</a></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RTP的H264载荷分析]]></title>
            <link>https://macrocborg.site/article/daceb9a2-92fe-4119-aa90-847ed1a75b89</link>
            <guid>https://macrocborg.site/article/daceb9a2-92fe-4119-aa90-847ed1a75b89</guid>
            <pubDate>Mon, 17 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[RTP是一种传输协议，常用于WebRTC领域，本文对RTP报文以及H264载荷的报文做了分析。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-full-width notion-block-daceb9a292fe4119aa90847ed1a75b89"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-96418c60619046b785dd1a633706e3fd" data-id="96418c60619046b785dd1a633706e3fd"><span><div id="96418c60619046b785dd1a633706e3fd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#96418c60619046b785dd1a633706e3fd" title="RTP Header解析"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">RTP Header解析</span></span></h3><ul class="notion-list notion-list-disc notion-block-2bf6878fcfa142ecaaf4c039d7d9ae92"><li>V：RTP协议的版本号，占2位，当前协议版本号为2</li></ul><ul class="notion-list notion-list-disc notion-block-6fe6bbcd74e24a569b100d0f18e2f126"><li>P：填充标志，占1位，如果P=1，则在该报文的尾部填充一个或多个额外的八位组，它们不是有效载荷的一部分。</li></ul><ul class="notion-list notion-list-disc notion-block-5090316d1b0f4ebe98ff9f540ca22e7d"><li>X：扩展标志，占1位，如果X=1，则在RTP报头后跟有一个扩展报头</li></ul><ul class="notion-list notion-list-disc notion-block-11734d99603347999c0f4f09f64a6e72"><li>CC：CSRC计数器，占4位，指示CSRC 标识符的个数</li></ul><ul class="notion-list notion-list-disc notion-block-f4f391a3b03a460a8889e4b496ba6367"><li>M: 标记，占1位，不同的有效载荷有不同的含义，对于视频，标记一帧的结束；对于音频，标记会话的开始。</li></ul><ul class="notion-list notion-list-disc notion-block-50c72a292b844d1a9880adf229af27cc"><li>PT: 有效荷载类型，占7位，用于说明RTP报文中有效载荷的类型，如GSM音频、JPEM图像等,在流媒体中大部分是用来区分音频流和视频流的，这样便于客户端进行解析。</li></ul><ul class="notion-list notion-list-disc notion-block-aacf88e46844407ebb6cdf2e266714ee"><li>序列号(sequence numbers)：占16位，用于标识发送者所发送的RTP报文的序列号，每发送一个报文，序列号增1。这个字段当下层的承载协议用UDP的时候，网络状况不好的时候可以用来检查丢包。同时出现网络抖动的情况可以用来对数据进行重新排序，序列号的初始值是随机的，同时音频包和视频包的sequence是分别记数的。</li></ul><ul class="notion-list notion-list-disc notion-block-594d24492f334af69a8f0fbf6d84323c"><li>时戳(Timestamp)：占32位，必须使用90 kHz 时钟频率。时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动，并进行同步控制。</li></ul><ul class="notion-list notion-list-disc notion-block-80ddf1a65de946edb1d7233816ff2d01"><li>同步信源(SSRC)标识符：占32位，用于标识同步信源。该标识符是随机选择的，参加同一视频会议的两个同步信源不能有相同的SSRC。</li></ul><ul class="notion-list notion-list-disc notion-block-6abd123ea7264b15951e422d05d53251"><li>特约信源(CSRC)标识符：每个CSRC标识符占32位，可以有0～15个。每个CSRC标识了包含在该RTP报文有效载荷中的所有特约信源。</li></ul><div class="notion-text notion-block-e73bbcaa03c24e57ab22ebb8f3654dcb">取一段码流如下：</div><div class="notion-text notion-block-29a9e3dcc74e495a8fcf663bb4ce45a7">其中
80     是V_P_X_CC
e0     是M_PT
00 1e  是SequenceNum
00 00 d2 f0 是Timestamp
00000000 是SSRC
把前两个字节换成二进制如下
1000 0000 1110 0000
按顺序解释如下:
10       是V；</div><div class="notion-text notion-block-03f9b5284f5647fca5c346fb81f6aa3d">0        是P；
0        是X；<s>
</s>0000     是CC；
1        是M；<s>
</s>110 0000 是PT;</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-d233dae744b24e5d8470c0a4e55bfc75" data-id="d233dae744b24e5d8470c0a4e55bfc75"><span><div id="d233dae744b24e5d8470c0a4e55bfc75" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d233dae744b24e5d8470c0a4e55bfc75" title="RTP载荷信息"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">RTP载荷信息</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b45ef6bdf6584b3f8374fec0c8211081" data-id="b45ef6bdf6584b3f8374fec0c8211081"><span><div id="b45ef6bdf6584b3f8374fec0c8211081" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b45ef6bdf6584b3f8374fec0c8211081" title="RTP载荷H264码流"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">RTP载荷H264码流</span></span></h4><ul class="notion-list notion-list-disc notion-block-fc729d95399d4b678d2df07f18b94ac3"><li>载荷方式有三种</li><ul class="notion-list notion-list-disc notion-block-fc729d95399d4b678d2df07f18b94ac3"><li>单个NAL单元包 荷载中只包含一个NAL单元 NAL头类型域等于原始单元类型 1-23。</li><li>聚合包 聚合多个NAL单元到单个RTP荷载中，单元类型是24,25,26,27。</li><li>分片单元 分片单个NAL单元到多个RTP包，FU-A, FU -B,单元类型28-29。
常用的打包时的分包规则是：如果小于MTU采用单个NAL单元包，如果大于MTU就采用FUs分片方式。</li></ul></ul><div class="notion-text notion-block-19ee83bbe5454272a054963f110cf9dc"><b>常用的打包方式就是单个NAL包和FU-A方式。</b></div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c256f3f21a4f4da3ac02e1b6bddf707b" data-id="c256f3f21a4f4da3ac02e1b6bddf707b"><span><div id="c256f3f21a4f4da3ac02e1b6bddf707b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c256f3f21a4f4da3ac02e1b6bddf707b" title="单个NAL单元包"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">单个NAL单元包</span></span></h4><div class="notion-text notion-block-096915511f9d4a58a22972ff0310a89d">定义在此的NAL单元包必须只包含一个。这意味着聚合包和分片单元不可以用在单个NAL单元包中。并且RTP序号必须符合NAL单元的解码顺序。NAL单元的第一字节和RTP荷载头第一个字节重合。
打包H264码流时，只需在帧前面加上12字节的RTP头即可。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ad12dfafad124369af377f2feb202dd1" data-id="ad12dfafad124369af377f2feb202dd1"><span><div id="ad12dfafad124369af377f2feb202dd1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ad12dfafad124369af377f2feb202dd1" title="分片单元(FU-A)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">分片单元(FU-A)</span></span></h4><div class="notion-text notion-block-48f1e88e576746fd9a173daac3d2529e">分片只定义于单个NAL单元不用于任何聚合包。NAL单元的一个分片由整数个连续NAL单元字节组成。每个NAL单元字节必须正好是该NAL单元一个分片的一部分。相同NAL单元的分片必须使用递增的RTP序号连续顺序发送(第一和最后分片之间没有其他的RTP包）。相似，NAL单元必须按照RTP顺序号的顺序装配。</div><div class="notion-text notion-block-3f3ab532b703452fb07dde4604066743">当一个NAL单元被分片运送在分片单元(FUs)中时，被引用为分片NAL单元。STAPs,MTAPs不可以被分片。 FUs不可以嵌套。 即, 一个FU 不可以包含另一个FU。运送FU的RTP时戳被设置成分片NAL单元的NALU时刻。</div><div class="notion-text notion-block-ed1deb85efe24dcaad1d735cda6ff0ca">表示FU-A的RTP荷载格式。FU-A由1字节的分片单元指示（如图5），1字节的分片单元头（如图6），和分片单元荷载组成。</div><div class="notion-text notion-block-1375a2f41a3743749ff78bd6a3e55a66">S: 1 bit 当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始，开始位设为0。</div><div class="notion-text notion-block-ef229439b71c48e48e8695ed47058ca7">E: 1 bit 当设置成1, 结束位指示分片NAL单元的结束，即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的 FU荷载不是分片NAL单元的最后分片,结束位设置为0。</div><div class="notion-text notion-block-b2b436577e1f4422b806b0894b0800da">R: 1 bit 保留位必须设置为0，接收者必须忽略该位</div><div class="notion-text notion-block-99cda0c41a4248a5979998035ecbee1e">打包时，原始的NAL头的前三位为FU indicator的前三位，原始的NAL头的后五位为FU header的后五位。
取一段码流分析如下：</div><div class="notion-text notion-block-b7828ce6d7a14b8bb913ccbd2d2dcee0">前12字节是RTP Header
7c是FU indicator
85是FU Header
FU indicator（0x7C）和FU Header（0x85）换成二进制如下
0111 1100 1000 0101
按顺序解析如下：
0　　　　是F
11　　　　是NRI
11100　　是FU Type，这里是28，即FU-A
1　　　　是S，Start，说明是分片的第一包
0       是E，End，如果是分片的最后一包，设置为1，这里不是
0        是R，Remain，保留位，总是0
00101    是NAl Type，这里是5，说明是关键帧（不知道为什么是关键帧请自行谷歌）
打包时，FUindicator的F、NRI是NAL Header中的F、NRI，Type是28；FU Header的S、E、R分别按照分片起始位置设置，Type是NAL Header中的Type。</div><div class="notion-text notion-block-422e088c2c3f409aa3725bba8626b1d2">解包时，取FU indicator的前三位和FU Header的后五位，即0110 0101（0x65）为NAL类型。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[win11 编译webrtcM109 for Windows]]></title>
            <link>https://macrocborg.site/article/compile webrtc</link>
            <guid>https://macrocborg.site/article/compile webrtc</guid>
            <pubDate>Thu, 27 Jul 2023 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-66baeeb4269343039e87c8a9d47f8292"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ec5d428be8e649da927efaa7e0c1e4b1" data-id="ec5d428be8e649da927efaa7e0c1e4b1"><span><div id="ec5d428be8e649da927efaa7e0c1e4b1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ec5d428be8e649da927efaa7e0c1e4b1" title="WebRTC编译库一览"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">WebRTC编译库一览</span></span></h2><table class="notion-simple-table notion-block-01c19f367c744dde9e7929b2a3d172e0"><tbody><tr class="notion-simple-table-row notion-block-fa855d9c1fa54b96b582b13c043c8d7e"><td class="" style="width:120px"><div class="notion-simple-table-cell">平台</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">目标平台</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">编译产物</div></td></tr><tr class="notion-simple-table-row notion-block-1cea72fbaf304a84bf006b289bc80486"><td class="" style="width:120px"><div class="notion-simple-table-cell">Android</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">armeabi-v7a、 arm64-v8a</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">.so静态库</div></td></tr><tr class="notion-simple-table-row notion-block-84688f7a478d439291c26820af6e47a9"><td class="" style="width:120px"><div class="notion-simple-table-cell">iOS</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">armv7、       arm64</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">.a静态库</div></td></tr><tr class="notion-simple-table-row notion-block-af8af0a8dbf9402a84f149766944b166"><td class="" style="width:120px"><div class="notion-simple-table-cell">Windows</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">x86 、x64</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">.lib静态库</div></td></tr><tr class="notion-simple-table-row notion-block-cfb9f64661504009b8bd862e584b5f66"><td class="" style="width:120px"><div class="notion-simple-table-cell">Linux</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">多种平台</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">.a静态库</div></td></tr></tbody></table><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-ea4941df59cb40c097efb716f72964d9" data-id="ea4941df59cb40c097efb716f72964d9"><span><div id="ea4941df59cb40c097efb716f72964d9" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ea4941df59cb40c097efb716f72964d9" title="系统要求"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">系统要求</span></span></h3><hr class="notion-hr notion-block-1681d7c03b394f8f9fcdbd66628deaa5"/><ul class="notion-list notion-list-disc notion-block-3320ff5d7f294ab39534ba8671acd560"><li>系统要求</li><ul class="notion-list notion-list-disc notion-block-3320ff5d7f294ab39534ba8671acd560"><li>具有至少8GB RAM 的 64 位 Intel 机器。强烈建议超过 16GB。</li><li>NTFS 格式的硬盘驱动器上至少有 100GB 的可用磁盘空间。FAT32 不起作用，因为某些 Git 包文件大于 4GB。</li><li>适当版本的 Visual Studio，如下所述。</li><li>Windows 10 或更新版本。</li></ul></ul><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-202f247c5ae9472e9e041e4b8f145267" data-id="202f247c5ae9472e9e041e4b8f145267"><span><div id="202f247c5ae9472e9e041e4b8f145267" class="notion-header-anchor"></div><a class="notion-hash-link" href="#202f247c5ae9472e9e041e4b8f145267" title="Windows 设置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Windows 设置</span></span></h3><hr class="notion-hr notion-block-20336888990d44199b15b88a7a781fee"/><div class="notion-text notion-block-c2da14097bc24b9bb5ed1f0026abc241">这里谷歌要求最好是VS2022(&gt;17.0.0)
必须勾选如下几项：</div><ul class="notion-list notion-list-disc notion-block-5a4c0fb82c0c41c99141684f59928620"><li>Desktop development with C++组件中10.0.20348.0或10.0.22000.0(win11)以上的Win10 SDK（如果没看到该版本，去左侧Individual components那里勾选）</li></ul><ul class="notion-list notion-list-disc notion-block-428f1382393a4828aabe680ddba97985"><li>使用<code class="notion-inline-code">C++ 进行桌面开发</code>组件</li></ul><ul class="notion-list notion-list-disc notion-block-a097d8ae770a4d13b956c27fab6c6ae5"><li><code class="notion-inline-code">MFC/ATL 支持</code>子组件</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-355b334c05864c58a45a6b55a31a73b8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F41fa804c-b92d-4f62-affe-c588aaf028f4%2FUntitled.png?table=block&amp;id=355b334c-0586-4c58-a45a-6b55a31a73b8" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a947563a2d814da1b2541852230ef3cc">安装完VS2022后，必须安装SDK调试工具。打开控制面板-&gt;程序与功能，找到刚才安装的最新Windows Software Development Kit（比如10.0.20348.0），鼠标右键-&gt;<span class="notion-red">修改</span></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c190c088b30f4be08ebc775b99bfe601"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8604f310-d297-4675-b48f-1864d5c1287b%2FUntitled.png?table=block&amp;id=c190c088-b30f-4be0-8ebc-775b99bfe601" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-778a860f07134141b7c58dbe9d2e4835">勾选Debugging Tools For Windows，然后点击修改。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8212a8a2b5aa472ab06900c1bc6229da"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F34315a4b-f323-4047-89da-09f04ce63ea8%2FUntitled.png?table=block&amp;id=8212a8a2-b5aa-472a-b069-00c1bc6229da" alt="notion image" loading="lazy" decoding="async"/></div></figure><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-cd8b06bef7654c50967b1f739e1c679a" data-id="cd8b06bef7654c50967b1f739e1c679a"><span><div id="cd8b06bef7654c50967b1f739e1c679a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cd8b06bef7654c50967b1f739e1c679a" title="下载源码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">下载源码</span></span></h4><ul class="notion-list notion-list-disc notion-block-577a609593314a1db4f048274a5f4ea7"><li>获取depot_tools
<code class="notion-inline-code">git clone &lt;https://chromium.googlesource.com/chromium/tools/depot_tools.git</code>&gt;
将depot_tools的路径加入系统环境变量<code class="notion-inline-code">Path</code>，然后移到最前面(避免已安装的python与git造成影响)。</li></ul><ul class="notion-list notion-list-disc notion-block-8a6e790c78d942939e9f6127e04ed117"><li>获取WebRTC源码
需要设置代理。</li></ul><div class="notion-text notion-block-6e30f4c539864812b4a5bbc5a164e950">打开windows命令行</div><div class="notion-text notion-block-4df85da801ae476bbb17922195c57d2d">如果一切顺利的话，这里应该可以看到已经在开始下载各部分内容。
如果有其他问题，可以仔细看下报错内容然后根据相应内容解决。</div><div class="notion-text notion-block-d546d1b55e8a48e1be54c2cca7a19372">可参考：</div><ul class="notion-list notion-list-disc notion-block-0927fd0619eb487aa3b657e513f332fd"><li>1.cipd.bat中修改powershell 为pwsd powershell5 跟powershell7 的执行程序变了</li></ul><ul class="notion-list notion-list-disc notion-block-cd6a224c67ab4b798ce273782332bb2c"><li>2.修改depottools中 /.cipd_bin/3.8/bin/Lib/subprocess.py
735 __init__中 <code class="notion-inline-code">shell=True</code></li></ul><div class="notion-text notion-block-6aa162bab0064d4982334137c181cb79">这一部分需要等待很久，代理及网速良好的情况下短则1-2小时，长则数小时仍没有明显变化，内容较多的部分是在<code class="notion-inline-code">../src/third_party</code>(12.5G左右)，所以最好保持电脑在下载期间不休眠或者关机
如果有部分内容获取较慢或者持续卡住的话，可以<code class="notion-inline-code">ctrl + c</code>,然后 <code class="notion-inline-code">gclient sync</code>继续同步。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-50eb792b0a9f4703aa8472f2cc330daa" data-id="50eb792b0a9f4703aa8472f2cc330daa"><span><div id="50eb792b0a9f4703aa8472f2cc330daa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#50eb792b0a9f4703aa8472f2cc330daa" title="开始编译"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开始编译</span></span></h4><div class="notion-text notion-block-0bf3edca066a48e2995637f2f5434050">打开x64 nativve tools vs2022</div><div class="notion-text notion-block-451dc34c3ccb46b6b5c165798588333c">生成VS工程文件，之前有些准备步骤需要在命令行输入，确定编译环境。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-07a3b6e6e95845019613853aeab4255a" data-id="07a3b6e6e95845019613853aeab4255a"><span><div id="07a3b6e6e95845019613853aeab4255a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#07a3b6e6e95845019613853aeab4255a" title="本机编译需要的命令"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">本机编译需要的命令</span></span></h4><ul class="notion-list notion-list-disc notion-block-6cd964edae8e46e4af6b1748f6127158"><li>-ide=vs 使用gn ninja 生成vs工程
编译好之后如果在vs中无法直接运行而且报错 找不到Ninja.exe
将ninja.exe 放到用户变量中</li></ul><div class="notion-text notion-block-2bf5957164a14f9b9f1c00d48a99f672">编译时需要使用clang的编译器
如果 Visual Studio 应用没配置 Clang 编译器，链接这个 webrtc.lib，生成工程文件时需要配置如下参数：</div><div class="notion-text notion-block-ceb91401fb7e4c0b9e47c32d8cbe499e">还需要禁用webrtc内部使用的stdcxx库(这一部分编译有点困难，经常报错)</div><div class="notion-text notion-block-e256c8c8470443a89601eca79b91641e"><b>如果需要添加ffmpeg_H264则必须打开clang编译器</b></div><div class="notion-text notion-block-2655acc515244be29bc5e53a9b1a0868">//ffmpeg_h264支持功能</div><ul class="notion-list notion-list-disc notion-block-fff069527f984a34b2f819cad4e2426d"><li><code class="notion-inline-code">is_debug=false</code></li></ul><ul class="notion-list notion-list-disc notion-block-432e49c787314f43922fe42ab59118c8"><li><code class="notion-inline-code">use_custom_libcxx=false </code> 是否使用内置的libcxx作为默认的c++标准库</li></ul><ul class="notion-list notion-list-disc notion-block-8cc9846f1d4d4ac5a0fefea5e2d968fd"><li><code class="notion-inline-code">rtc_include_tests=false</code></li></ul><ul class="notion-list notion-list-disc notion-block-e8db7da1a162408f9dbc209ec89cbb04"><li><code class="notion-inline-code">is_component_build=false</code> 是否使用动态运行库 false表示使用静态运行期库 Release版本对应MT，Debug版本对应MTD</li></ul><ul class="notion-list notion-list-disc notion-block-fedd39b0eecf41da89b9e82fa4533a67"><li><code class="notion-inline-code">symbol_level=0</code> 裁剪包</li></ul><ul class="notion-list notion-list-disc notion-block-d0d0128c09a8437888a9f9656a7d033a"><li><code class="notion-inline-code">proprietary_codecs=true</code> H264</li></ul><ul class="notion-list notion-list-disc notion-block-30a23896599c41b2a9ee0ddfcdb1956b"><li><code class="notion-inline-code">rtc_use_h264=true</code> 是否使用H264。注意Windows平台编码使用OpenH264，解码使用ffmpeg</li></ul><ul class="notion-list notion-list-disc notion-block-0cf205f1633449a282468a1b47fc4335"><li><code class="notion-inline-code">ffmpeg_branding=\\&quot;Chrome\\&quot;</code> ffmpeg的分支名，采用Chrome的分支</li></ul><ul class="notion-list notion-list-disc notion-block-01b2b18014df4527aa562bdd16745029"><li><code class="notion-inline-code">is_clang=true</code></li></ul><ul class="notion-list notion-list-disc notion-block-8875ddf087464d61a3568b8ee1812005"><li><code class="notion-inline-code">use_lld=false</code></li></ul><ul class="notion-list notion-list-disc notion-block-71da7f0ecbbd45e08d6a1f9aa88618e4"><li><code class="notion-inline-code">treat_warnings_as_errors=false</code></li></ul><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-467eb8d065e24d0dbecc1455806b0974" data-id="467eb8d065e24d0dbecc1455806b0974"><span><div id="467eb8d065e24d0dbecc1455806b0974" class="notion-header-anchor"></div><a class="notion-hash-link" href="#467eb8d065e24d0dbecc1455806b0974" title="错误点1"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">错误点1</span></span></h4><div class="notion-text notion-block-9c8392a809e8406fae98761d91185a53">5414版本可能会报这个错误，按照错误提示修改一下就行。
修改源码的std::towupper 为::towupper</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-5fab2171e1234372bf08a3213bba0b14" data-id="5fab2171e1234372bf08a3213bba0b14"><span><div id="5fab2171e1234372bf08a3213bba0b14" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5fab2171e1234372bf08a3213bba0b14" title="错误点2"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">错误点2</span></span></h4><div class="notion-text notion-block-cb8bb693fd96498381a690a04d135b42">build/toolchain/win/tool_wrapper.py
提示unicode utf8错误   在对应的文件内将utf8字样修改为gbk</div><div class="notion-text notion-block-f69c00e7ebd041c3b9f00de15eb06953">就可以在 <code class="notion-inline-code">out/vs2022_m109_x64_release_ffmpeg_h264</code>下面找到VS工程文件了。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-9e5e4b557eb84b89ab17fad4994eba4e" data-id="9e5e4b557eb84b89ab17fad4994eba4e"><span><div id="9e5e4b557eb84b89ab17fad4994eba4e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9e5e4b557eb84b89ab17fad4994eba4e" title="引用WebRTC库"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">引用WebRTC库</span></span></h4><div class="notion-text notion-block-6e10a3e3c84143b9b84ec64e8f9f1e71">WebRTC编译后会在src\out\Default\obj目录下生成整个WebRTC工程的静态库：webrtc.lib，就这个是完整的包，如果只想编译部分也是可以的。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8699e3806e924070b3d9af89f3b0bd0a" data-id="8699e3806e924070b3d9af89f3b0bd0a"><span><div id="8699e3806e924070b3d9af89f3b0bd0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8699e3806e924070b3d9af89f3b0bd0a" title="参考"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">参考</span></span></h2><div class="notion-text notion-block-1ae51d5411e04f44b1ab3229e1323104">[1] <a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md">https://chromium.googlesource.com/chromium/src/+/master/docs/windows_build_instructions.md</a></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WebRTC Native添加H264+OpenSSL支持]]></title>
            <link>https://macrocborg.site/article/WebRTC Native add H264+OpenSSL</link>
            <guid>https://macrocborg.site/article/WebRTC Native add H264+OpenSSL</guid>
            <pubDate>Tue, 06 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[H264是比较常用的编解码格式，本文将向你介绍如何在Win11操作系统上为WebRTC库设置H264编解码器。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-504de28093f94560861ac9fa36fc7295"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-bb10552c543640d4b81e9ae2a43d66ad"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">给WebRTC静态库在Windows下使用增加一些支持内容：
在Windows下使用WebRTC.lib完成PeerConnection的通话，代码写完之后，发现程序虽然通了，但是It dosn’t work! 通过追查，发现是一个简单的问题，WebRTC在Windows 下默认使用的是VP8编码格式，而我们使用的服务器选择的是H264编解码，在SDP信息交换中的格式对不上，所以，需要在编码时给WebRTC指定一下编码格式。</div></div><div class="notion-blank notion-block-4e33a80996de43889b201ed8e1f52bf1"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-c63bd2d1f4124b058c8e7adaa9c6ac04" data-id="c63bd2d1f4124b058c8e7adaa9c6ac04"><span><div id="c63bd2d1f4124b058c8e7adaa9c6ac04" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c63bd2d1f4124b058c8e7adaa9c6ac04" title="📝WebRTC Windows版编译(添加H264+OpenSSL支持)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝WebRTC Windows版编译(添加H264+OpenSSL支持)</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-62a62ca6690048d7a4e3c7b9cb3c088c" data-id="62a62ca6690048d7a4e3c7b9cb3c088c"><span><div id="62a62ca6690048d7a4e3c7b9cb3c088c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#62a62ca6690048d7a4e3c7b9cb3c088c" title="概要："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">概要：</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-ba564b05e1c74680a6bdf64b1e0ca6c7" data-id="ba564b05e1c74680a6bdf64b1e0ca6c7"><span><div id="ba564b05e1c74680a6bdf64b1e0ca6c7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ba564b05e1c74680a6bdf64b1e0ca6c7" title="版本配置信息"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">版本配置信息</span></span></h3><table class="notion-simple-table notion-block-8f8f9f9b1c1f4d6cbc05c52a9eec14e2"><tbody><tr class="notion-simple-table-row notion-block-9efa5a7ec51f4d5d915df319efd237f8"><td class="" style="width:120px"><div class="notion-simple-table-cell">配置名称</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">版本</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">介绍</div></td></tr><tr class="notion-simple-table-row notion-block-4da155f6e04f4036a7d50e26d2481e7c"><td class="" style="width:120px"><div class="notion-simple-table-cell">WebRTC版本</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">M109</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">//5414</div></td></tr><tr class="notion-simple-table-row notion-block-9247841bfff44141a678d0576fd0f9d9"><td class="" style="width:120px"><div class="notion-simple-table-cell">Windows</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">win11</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td></tr><tr class="notion-simple-table-row notion-block-0a1d51b3b58e4c54a7cccfa45e822ddc"><td class="" style="width:120px"><div class="notion-simple-table-cell">H264</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">chrome</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">主线版本</div></td></tr><tr class="notion-simple-table-row notion-block-464808ba488944b8918e6dc9f86033ac"><td class="" style="width:120px"><div class="notion-simple-table-cell">OpenSSH</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">3.0.8</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td></tr></tbody></table><div class="notion-text notion-block-f6a637d673334ace9740bbd33473c967">因为在现有业务环境下，需要HTTPS,当前的工具链是libcurl +openssh + webrtc，而webrtc中其实有自己的openssh分支，叫<code class="notion-inline-code">boringssl</code>，但是如果使用了这个谷歌版本的boringssl，会引起库冲突，试想一下，同样的一个库但是确是不同名字。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-8c42691e9e9c475583b8233d5b050900" data-id="8c42691e9e9c475583b8233d5b050900"><span><div id="8c42691e9e9c475583b8233d5b050900" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8c42691e9e9c475583b8233d5b050900" title="为什么需要添加H264支持"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么需要添加H264支持</span></span></h3><div class="notion-blank notion-block-2b501ffde0d546bcb1f0eddfe68da43c"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[WebRTC封装静态库]]></title>
            <link>https://macrocborg.site/article/WebRTC封装静态库</link>
            <guid>https://macrocborg.site/article/WebRTC封装静态库</guid>
            <pubDate>Tue, 06 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[本文用于记录在Win11环境下，封装WebRTC-Native-M109版本的动态库调用库的过程。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-d852c3464bce4655bbb1336521193a3f"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-c521507c62da4b56b0f30504770541c6" data-id="c521507c62da4b56b0f30504770541c6"><span><div id="c521507c62da4b56b0f30504770541c6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c521507c62da4b56b0f30504770541c6" title="📥WebRTC封装桌面采集功能"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📥<b>WebRTC封装桌面采集功能</b></span></span></h3><div class="notion-blank notion-block-ca7ef6fca7444124865559f5ad950a9c"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-a1c4d020a8c24a579aa3eb0d62d60635" data-id="a1c4d020a8c24a579aa3eb0d62d60635"><span><div id="a1c4d020a8c24a579aa3eb0d62d60635" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a1c4d020a8c24a579aa3eb0d62d60635" title="简介"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">简介</span></span></h4><div class="notion-text notion-block-f4d171f330eb4fefb15c4670830dae6a">本文用于记录在Win11环境下，封装WebRTC-Native-M109版本的动态库调用库的过程。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-5e016c2fe400411ba7232034bb9c6ac2" data-id="5e016c2fe400411ba7232034bb9c6ac2"><span><div id="5e016c2fe400411ba7232034bb9c6ac2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5e016c2fe400411ba7232034bb9c6ac2" title="环境"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">环境</span></span></h4><ul class="notion-list notion-list-disc notion-block-70ab7963fc7243b488258f8f27984c63"><li>win11</li></ul><ul class="notion-list notion-list-disc notion-block-55103fb934c34fd5bf804c2e62bc3b46"><li>WebRTC M109</li></ul><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3d3bfd48ff114536a71e84bd793af19c" data-id="3d3bfd48ff114536a71e84bd793af19c"><span><div id="3d3bfd48ff114536a71e84bd793af19c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3d3bfd48ff114536a71e84bd793af19c" title="正文"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">正文</span></span></h4><div class="notion-text notion-block-547cc54b62a649cbae06d06eb3da596c">本次编译工作是基于成功使用WebRTC推流桌面到SRS服务器的Demo，将屏幕共享功能独立抽离出来，也为以后动态编译其他模块的工作打个底。</div><div class="notion-text notion-block-7944fe8d31544b5ba1d2530984b8e899">话不多说</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b294bebd1a5944adbc8fe3d53ae9b828" data-id="b294bebd1a5944adbc8fe3d53ae9b828"><span><div id="b294bebd1a5944adbc8fe3d53ae9b828" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b294bebd1a5944adbc8fe3d53ae9b828" title="Step1. 编译通过封装项目"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Step1. 编译通过封装项目</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-9e232d618e6f4ed58c7d79871e2e232f" data-id="9e232d618e6f4ed58c7d79871e2e232f"><span><div id="9e232d618e6f4ed58c7d79871e2e232f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9e232d618e6f4ed58c7d79871e2e232f" title="Step2.封装库需要注意的点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Step2.封装库需要注意的点</span></span></h4><ul class="notion-list notion-list-disc notion-block-06af05448743410fb390af8136c20517"><li>C/C++ 不同封装的区别 [[深入静态库、动态库]]</li></ul><ul class="notion-list notion-list-disc notion-block-9fac6e9348b24827ac6270f38112215a"><li>几条代码之间的区别 函数调用方式 <code class="notion-inline-code">__stdcall</code>跟<code class="notion-inline-code">__cdecl</code> 参考 [[函数调用方式 __stdcall跟__cdecl详解]]
这里得到的结论之一是<em><b>如果你的程序中没有涉及可变参数，最好使用__stdcall</b></em></li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-404647dda2df41159b0d2b7610736113" data-id="404647dda2df41159b0d2b7610736113"><span><div id="404647dda2df41159b0d2b7610736113" class="notion-header-anchor"></div><a class="notion-hash-link" href="#404647dda2df41159b0d2b7610736113" title="遇到的问题以及思考"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">遇到的问题以及思考</span></span></h3><div class="notion-text notion-block-93c8220a854d45f89300e171451fda3d">        编译过程中，有一个问题困扰了我一段时间，就是一个网络类的信号槽无法响应。具体情况是这样，在Qt的主线程中有一个调用类A，它负责调用SDK中封装的C风格函数，我在A的一个方法中使用lambda调用SDK函数创建了一个Controller,然后在A-&gt;First 方法中调用SDK::CreateDomain,并把A::FirstCallback作为回调传入了CreateDomain中，并且SDK把回调存储起来，在经过一段时间后，SDK::GetMessage获得了讯息，开始调用A::FirstCallback，我在FirstCallback中使用了网络请求，但是槽函数始终无法响应，但是把它单独拎出来发放在主线程执行也可以得到响应。做让我们来梳理一下。见下列代码。</div><div class="notion-blank notion-block-05100da452ba4a4e9a15789d21cc0d60"> </div><div class="notion-text notion-block-e9bef0ea49814c53904ad7d1ad559f52">main.h</div><div class="notion-text notion-block-0eb41ccd83f148319091533f2197985b">    </div><div class="notion-text notion-block-d656808d928c42659c9ec4b95e7b23c4">      这里使用了一个<b><code class="notion-inline-code">技巧</code></b><b> </b>，因为在库函数中定义的<code class="notion-inline-code">SDK::SetCallback</code>的回调函数 是纯函数指针，把A的普通成员函数作为回调是不行的，因为不存在 从类的成员函数的指针直接转化成函数指针的隐式转换，所以这里我们面临有几个选择
1: 手搓一个转化方法，让这个类成员函数指针转化成对应的函数指针，这很麻烦，而且不一定能实现，我放弃。
2：使用static 修饰另一个函数，当然，使用static修饰之后 ，这个函数就不属于这个类了，具体细节参考<a target="_blank" rel="noopener noreferrer" class="notion-link" href="notion://www.notion.so/macrocyborg/be18bd8f453f4e2794df2aa4f32642f0">static深入理解</a>，然后在这个static函数中调用原本的想要调用的A::FirstCallback，这相当于一次桥接。这样实现也不是很优雅，函数调来调去看上去比较凌乱。暂时放弃。
3：使用喜闻乐见的lambda委托一下，跟第二种其实很类似，但是lambda可以直接被传入当作参数，更方便与高效，笔者正是使用的这个方式。</div><div class="notion-text notion-block-51f891bd84914c018d34a25def4c544b">
class_a.h</div><div class="notion-text notion-block-087da301defa4d34977c1156661c3f81">       那么从现在开始，函数执行栈执行到了SDK::SetCallBack，我们知道，被调用的函数运行结束后当前帧全部收缩，回到调用者的帧,而在这里，我们使用的是匿名函数，他其实在传入的时候是作为闭包对象，并且分配在堆上，并没有传入函数调用栈，栈上只保存了必要的帧信息。
![[Pasted image 20230601103935.png]]</div><div class="notion-text notion-block-7b390b5a6ed747c58a65f1b7ab66fa43">HttpManager 是一个继承自QObject的单例类
http_manager.h</div><div class="notion-text notion-block-f0e022e83c6e4735898d9a56a4cd927e">sdk.h</div><div class="notion-text notion-block-d85550aa744a496b91e8ba68908c0324"><b>重点来了</b>，此时，我们执行到了SDK::SetCallback,而SetCallback中给固定的一个session对象设置了回调函数，那么此时，通过闭包就已经传递到了sdk库内的session对象中，然后在SetCallback中通过特定的事件机制，通过线程异步延迟在OnCall得到了响应，此时OnCall是在SDK函数内部的子线程内，因此，在OnCall内部调用的<code class="notion-inline-code">ses_-&gt;mfirst_callback((void*)_ses_,message.c_str(),ses-&gt;mfirst_callback_usr_);</code> <b>自然也是在子线程的函数调用栈上！</b>，线程有自己独立的函数调用栈，理解这一点尤为重要。那么回到调用，在这个子线程中，回到了A的函数A::FirstCallback上，我们再回顾一下这个函数，</div><div class="notion-text notion-block-2c69470b4c6040679609d1cf97652f77">此时一切正常，顺利走入HttpManager-&gt;postRequest()中，并传递了一个闭包给HttpManager作为回调保存下来。
但是，所有的消息在m_accessManager Post请求出去之后石沉大海，没有响应。</div><div class="notion-text notion-block-e0cafa9af1d9405c9d716a6c24d054f1">一开始笔者排除了几个方向</div><ul class="notion-list notion-list-disc notion-block-7dd19436ff3a4aa3ba768510c59438e5"><li>HttpManager的构造函数接受了调用者作为父类对象，而它的成员对象 <code class="notion-inline-code">m_accessManager</code>把调用者作为父类对象，因此执行Post请求跟需要接受的槽函数类不在同一个线程，所以只要将Connect申明成跨线程调用就可以了？ 但是证实无效</li></ul><ul class="notion-list notion-list-disc notion-block-49af696301404eaf93c3ba72b0c63033"><li>使用笔者总结的另外一套常用的网络模型，核心方法是moveToThread,通过Controller来控制内部线程的一切I/O请求，所有参数通过信号槽传递。 这套方法可以是可以，但是信息部分都是通过信号槽来传递的，我有意的在新的网络模型中寻求更高效的方式，所以这套作为备用。</li></ul><ul class="notion-list notion-list-disc notion-block-0c12b712dca140949b8260a7accfcf74"><li>其他的方法都太过于黑魔法，确实可行，但是不适合在项目工程中使用，比较破坏编程规范，这里也不再赘述。
还有两个方向，手搓事件类使用Qt自带的跨线程异步回调相关的类 QEventLoop或者QInvoke,写代码的时候不宜尝试过多，项目中能用且可控是第一要义，需要快速产出，所以使用了QEventLoop。把FirstCallback内部包起来，形成一个loop,lambda闭包回来的时候因为loop没有退出，所以m_accessManager 的槽函数能响应到。这样确实可行，但是有个问题，eventloop会阻塞主线程，也就是Ui线程，但是这里使用起来确实是没问题的，渲染会在另外的线程中执行，这里只是不能退出。</li></ul><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-8bfd1f617e5640dab8554520e944859e" data-id="8bfd1f617e5640dab8554520e944859e"><span><div id="8bfd1f617e5640dab8554520e944859e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8bfd1f617e5640dab8554520e944859e" title="一点思考："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一点思考：</span></span></h3><div class="notion-text notion-block-a1c2f79502824e5e91d8761880d4a408">所以前面的问题，大概方向是，<code class="notion-inline-code">QNetworkAccessManager</code> 对象所在的线程与接收信号的对象不在同一个线程，可能会导致信号无法正确触发。但是其实都是基于QObject,connect函数设置成异步调用，为什么不能触发这一点还没有特别清楚。还有它的生命周期应该是全局的，但是生效条件比较苛刻，这一点可能跟SDK库中的环境也有关。</div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-2d760df160c94d31956cc000727b2b48" data-id="2d760df160c94d31956cc000727b2b48"><span><div id="2d760df160c94d31956cc000727b2b48" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2d760df160c94d31956cc000727b2b48" title="写在最后"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">写在最后</span></span></h3><ul class="notion-list notion-list-disc notion-block-9644fd64467148a2bcf5770c1573a5ec"><li>代码中需要有I/O对象的时候，需要特别关注对象的生命周期</li></ul><ul class="notion-list notion-list-disc notion-block-013a5377465e43078456a3dbc8c1c1ef"><li>对于回调函数需要谨慎使用，使用者应该明确内部对象的生命周期，确实很容易出现线上问题。</li></ul><ul class="notion-list notion-list-disc notion-block-f9a6959bd7754906988894924fada710"><li>学无止境~</li></ul></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[如何理解协程-以st-thread为例]]></title>
            <link>https://macrocborg.site/article/coroutine</link>
            <guid>https://macrocborg.site/article/coroutine</guid>
            <pubDate>Tue, 11 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[协程创建的时间其实很早，跟线程等概念出现时期很接近，本文以st-thread 为例向你介绍协程的一些特点]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-ad35a1f18a2a447b80ebd0ea62538646"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-9404a13e59a343acb63076d7dae2efad" data-id="9404a13e59a343acb63076d7dae2efad"><span><div id="9404a13e59a343acb63076d7dae2efad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9404a13e59a343acb63076d7dae2efad" title="如何理解协程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">如何理解协程</span></span></h2><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-0a7f961094bc43439eefda62b678e121"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fbc135d64-9d83-4f3b-947d-837f00c5ecb3%2FUntitled.png?table=block&amp;id=0a7f9610-94bc-4343-9eef-da62b678e121" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-0fa5a16bf5ee43c49c055d6e7b0147fe">协程相比之与进程、线程，更像是用户自己实现的库函数，是在操作系统之上的操作，保存堆栈上下文信息。</div><div class="notion-text notion-block-99be55629d3e400c8047e4c3a6e9db3a">二.进程、线程、协程三者的上下文切换比较</div><table class="notion-simple-table notion-block-fcc4c6b159c2447c8bef7accd6bb412b"><tbody><tr class="notion-simple-table-row notion-block-3f89f6cbba9b4c068c200abd12ac46e5"><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">进程</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">线程</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">协程</div></td></tr><tr class="notion-simple-table-row notion-block-5d6f85bc814d4fa3a5b77896bc484c05"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换者</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">操作系统</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">操作系统</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用户（编程者/应用程序</div></td></tr><tr class="notion-simple-table-row notion-block-4cd9653e73dd450d908f6ce5cd702f21"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换时机</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">根据操作系统自己的切换策略，用户不感知</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">根据操作系统自己的切换策略，用户不感知</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用户自己的程序决定</div></td></tr><tr class="notion-simple-table-row notion-block-d86253550ea742b1a120ca389dc17034"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换内容</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">页全局目录，内核栈，硬件上下文</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">内核栈，硬件上下文</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">硬件上下文</div></td></tr><tr class="notion-simple-table-row notion-block-a40eae459f874d418fe4e594a3f8772f"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换内容的保存</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保存于内核栈中</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保存于内核栈中</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">保存在用户自己的变量（用户栈或堆）</div></td></tr><tr class="notion-simple-table-row notion-block-4e66485bcf834072a7819f71ee42914b"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换过程</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用户态 - 内核态 - 用户态</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用户态 - 内核态 - 用户态</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">用户态（没用进入内核态）</div></td></tr><tr class="notion-simple-table-row notion-block-22fa6b54321e4e5d85ff15cdd7df16bb"><td class="" style="width:120px"><div class="notion-simple-table-cell">切换效率</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">低</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">中</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">高</div></td></tr><tr class="notion-simple-table-row notion-block-d4a91ea89eaa4244b87d55bec33b912f"><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td><td class="" style="width:120px"><div class="notion-simple-table-cell">ㅤ</div></td></tr></tbody></table><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8f54c81409a74a1eb5a4f5605abeaf97" data-id="8f54c81409a74a1eb5a4f5605abeaf97"><span><div id="8f54c81409a74a1eb5a4f5605abeaf97" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8f54c81409a74a1eb5a4f5605abeaf97" title="协程的利与弊"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">协程的利与弊</span></span></h2><div class="notion-text notion-block-236307060e7b47d18e0a32f7a1f08480">代码风格更易于理解，代码复用更方便</div><div class="notion-text notion-block-4d6da186d81e4ba9b9b035146e5f0737"><b>协程最大的问题就是无法利用CPU多核</b></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-7f86b645c0f444818d0a6bbd70192ab1" data-id="7f86b645c0f444818d0a6bbd70192ab1"><span><div id="7f86b645c0f444818d0a6bbd70192ab1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7f86b645c0f444818d0a6bbd70192ab1" title="协程应用场景"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">协程应用场景</span></span></h2><div class="notion-text notion-block-688cbd99ff044e9d969c761c229abad5">一个线程内的多个协程是串行执行的，不能利用多核，所以，显然，协程不适合计算密集型的场景。协程适合I/O 阻塞型。
I/O本身就是阻塞型的（相较于CPU的时间世界而言）。就目前而言，无论I/O的速度多快，也比不上CPU的速度，所以一个I/O相关的程序，当其在进行I/O操作时候，CPU实际上是空闲的。
我们假设这样的场景，如下图：1个线程有5个I/O的事情（子程序）要处理。如果我们绝对的串行化，那么当其中一个I/O阻塞时，其他4个I/O并不能得到执行，因为程序是绝对串行的，5个I/O必须一个一个排队等待处理，当一个I/O阻塞时，其它4个也得等着。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-2e2da35b16364b9a940c5f1b0b99e3af" data-id="2e2da35b16364b9a940c5f1b0b99e3af"><span><div id="2e2da35b16364b9a940c5f1b0b99e3af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2e2da35b16364b9a940c5f1b0b99e3af" title="关于 State-Thread 的一个问题思考"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">关于 State-Thread 的一个问题思考</span></span></h2><div class="notion-text notion-block-2282c37a29cd4a22a2cd0b1e38599ea9">关于st源码分析-运行协程文章 阅读中的一个思考，文中指出 State-Thread 在执行restoreWork的时候，在内部封装recevfrom,函数，主要是在idle主协程中，判断切换所有协程的sendto，发送域名查询请求后，再切换到idl来进行阻塞，其根本原理同手动执行所有sendto,再执行select/epoll一样，只是协程的st_sendto跟st_recvfrom看起来是顺序执行的。</div><div class="notion-text notion-block-a72501ee3b6748df9e94063dba50ed01">如果说state thread  协程其实本质是对系统的select /epoll 进行封装的话，那么在什么时候进行切换是由库决定还是必须人工想好每个切换点，然后利用协程的切换去做这个事情。</div><div class="notion-text notion-block-6767a7fe8c9b40dca9556525bcf7efff">除了 idle 协程，其他所有协程做的事情都是对于 在 系统线程 看来都是非阻塞，非阻塞协程干的话，就是把 需要监听的 fd 放进去全局变量 fd_set，然后由 idle 协程 执行 select() 函数阻塞，等待信号。ST的调度策略是 _ST_RUNQ 里面已经没有协程要运行了，才会切换到 idle 协程来阻塞。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-c47c793c1213464dbb190f3e8d426e3e" data-id="c47c793c1213464dbb190f3e8d426e3e"><span><div id="c47c793c1213464dbb190f3e8d426e3e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c47c793c1213464dbb190f3e8d426e3e" title="State-Thread——Sleep"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">State-Thread——Sleep</span></span></h2><div class="notion-text notion-block-a47ddfaf835b4a60b50bfa9bed06ebf9">由于协程实际上是在单线程中运行，如果需要sleep而调用系统的sleep或者usleep的话会阻塞整个线程，所以协程内部需要实现自己的sleep, state-Thread是这样做的：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3268084425214724913e499db2b55efd" data-id="3268084425214724913e499db2b55efd"><span><div id="3268084425214724913e499db2b55efd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3268084425214724913e499db2b55efd" title="st_usleep(st_utime_t usecs)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">st_usleep(st_utime_t usecs)</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-a29a8b7ba5824165a408b9013c362f96" data-id="a29a8b7ba5824165a408b9013c362f96"><span><div id="a29a8b7ba5824165a408b9013c362f96" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a29a8b7ba5824165a408b9013c362f96" title="_st_idle_thread_start(void *arg)"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">_st_idle_thread_start(void *arg)</span></span></h3><ol start="1" class="notion-list notion-list-numbered notion-block-8f586e40afeb49d3b50db80dc15046e5"><li>通过 引入一个协程状态 ST_ST_SLEEPING</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-8923d104887248e889074217cd607d7a"><li>将a协程加入<code class="notion-inline-code">SLEEPQ</code>队列中，然后使用<code class="notion-inline-code">_ST_SWITCH_CONTEXT()</code>切换其他协程，此时协程a的状态相当于挂起</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-e058c66f2db044cb9c54f9769b954ca7"><li>在最终的<code class="notion-inline-code">_st_idle_thread_start()</code>中，通过<code class="notion-inline-code">_st_vp_check_clock()</code>处理所有进入<code class="notion-inline-code">_ST_ST_SLEEPING</code>状态的协程，通过比对a协程加入SLEEPQ队列的时间值是否满足睡眠时间来做出下一步决断。</li></ol><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-1f173b34b4c6457d96e058752fe38391" data-id="1f173b34b4c6457d96e058752fe38391"><span><div id="1f173b34b4c6457d96e058752fe38391" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1f173b34b4c6457d96e058752fe38391" title="State-Thread——协程通信"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">State-Thread——协程通信</span></span></h2><div class="notion-blank notion-block-85fe2d4166b34026a901e623e4746ad8"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>