【音视频 | Ogg】RFC3533 :Ogg封装格式版本 0(The Ogg Encapsulation Format Version 0)

news2024/11/8 2:54:58

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍Ogg封装格式🍭
😎金句分享😎:🍭子曰:君子坦荡荡,小人长戚戚。——《论语·述而篇》。意思是,君子心胸开阔,神定气安;小人斤斤计较,患得患失。🍭

目录

  • 🎄一、介绍
  • 🎄二、定义
  • 🎄三、通用封装格式的要求
  • 🎄四、Ogg比特流格式
  • 🎄五、封装过程
  • 🎄六、Ogg页面格式


在这里插入图片描述

🎄一、介绍

Ogg比特流格式是作为一个更大项目的一部分开发的,该项目旨在创建一组用于多媒体内容(编解码器)编码和解码的组件,这些组件将在软件和硬件方面免费提供并可免费重新实现,以供包括互联网社区在内的广大计算社区使用。以Xiph.Org为代表的Ogg开发人员的意图是,它可以在没有知识产权问题的情况下使用。

本文档描述了Ogg比特流格式,以及如何使用它来封装由一个或多个编码器创建的一个或几个媒体比特流。Ogg传输比特流旨在为由原始、未封装数据包组成的高级编解码器流提供成帧、错误保护和查找结构,例如Vorbis音频编解码器或即将推出的Tarkin和Theora视频编解码器。它能够交织不同的二进制媒体和其他时间连续的数据流,这些数据流由编码器准备为数据包序列。Ogg提供了足够的信息来在原始分包边界处将数据适当地分离回这样的编码器创建的数据分包,而不依赖于解码来找到分包边界(packet boundaries)。

请注意,MIME类型应用程序/ogg已在IANA注册。

在这里插入图片描述

🎄二、定义

为了描述Ogg封装过程,将使用一组术语,其含义需要充分理解。因此,在我们开始描述通用媒体流封装格式的要求、封装过程和Ogg比特流的具体格式之前,现在已经定义了一些最基本的术语。有关更完整的词汇表,请参阅附录。

Ogg封装的结果被称为“物理(Ogg)比特流”。它封装了一个或多个编码器创建的比特流,称为“逻辑比特流”。提供给Ogg封装过程的逻辑比特流具有一种结构,即它被拆分为一系列所谓的“数据包”。分包由该逻辑比特流的编码器创建,并且仅代表该编码器的有意义的实体(例如,未压缩流可以使用视频帧作为分包)。它们不包含边界信息——串在一起,看起来像是没有地标的随机字节流。

请注意,本文件中“数据包”(packet)一词并非用于表示通过网络传输的实体。

在这里插入图片描述

🎄三、通用封装格式的要求

Ogg背后的设计思想是提供一种通用的线性媒体传输格式,以实现独立于媒体数据的编码格式的一个或多个交织媒体流的基于文件的存储和基于流的传输。这种封装格式需要提供:

  • 逻辑比特流的成帧。
  • 不同逻辑比特流的交错。
  • 腐败检测。( detection of corruption. )
  • 解析错误后重新捕获
  • 用于直接随机访问比特流中任意位置的标志.
  • 流传输能力(即不需要寻找来构建100%完整的比特流)。
  • 小开销(即,使用不超过比特流带宽的大约1-2%用于分包边界标记、高级成帧、同步和查找)。
  • 实现快速解析的简单性。
  • 几个物理比特流的简单连接机制。

Ogg考虑了所有这些设计因素。Ogg支持逻辑比特流的成帧和交织、寻找地标、检测损坏以及在解析错误后重新同步流,开销不超过1-2%。它是一个通用框架,用于对时间连续的比特流进行封装。它不知道它封装的编解码器数据的任何细节,因此独立于任何媒体编解码器。
在这里插入图片描述

🎄四、Ogg比特流格式

物理Ogg比特流由多个逻辑比特流组成,这些逻辑比特流交错在所谓的“页面”中。从在页面级别复用的多个逻辑比特流中按顺序获取整个页面。逻辑比特流由物理比特流的每个页面的报头中的唯一序列号来标识。这个唯一的序列号是随机创建的,与它所代表的逻辑比特流的内容或编码器没有任何连接。所有逻辑比特流的页面都是并发交错的,但它们不需要按规则顺序排列——它们只需要在逻辑比特流中是连续的。Ogg多路分解通过从物理比特流按顺序获取页面并将其重定向到适当的逻辑解码实体来从物理比特串流重构原始逻辑比特流。

每个Ogg页面(page)只包含一种类型的数据,因为它只属于一个逻辑位流。页面大小可变,并且具有包含封装和错误恢复信息的页头。物理Ogg比特流中的每个逻辑比特流都以一个特殊的起始页(bos=beginning of stream)开始,并以一个特定的页(eos=end of stream)结束。

bos页面包含唯一标识编解码器类型的信息,并且可能包含设置解码过程的信息。bos页面还应该包含有关编码媒体的信息——例如,对于音频,它应该包含采样率和通道数量。按照惯例,bos页面的第一个字节包含唯一标识所需编解码器的神奇数据(magic data)。任何部署新编解码器的人都有责任确保能够可靠地将他/她的编解码器与使用中的所有其他编解码器区分开来。没有固定的方法来检测编解码器识别标记的结束。bos页面的格式取决于编解码器,因此必须在该逻辑比特流类型的封装规范中给出。Ogg还允许但不要求逻辑比特流的bos页之后的辅助报头分包,并且这些报头分包还必须在任何逻辑比特流中的任何数据分包(data packets)之前。这些随后的报头分包(header packets)被添加到完整个数的页面(page)中,这些页面(page)将不包含任何数据分包。因此,物理比特流从所有逻辑比特流的每个页面包含一个初始报头分包的bos页面开始,然后是所有流的子报头分包,然后是包含数据分包的页面。

一个或多个逻辑比特流的封装规范称为“媒体映射”。媒体映射的一个例子是“Ogg Vorbis”,它使用Ogg框架来封装Vorbis编码的音频数据,用于基于流的存储(如文件)和传输(如TCP流或管道)。Ogg Vorbis提供了Vorbis编解码器的名称和版本,音频速率和音频质量在Ogg Vorpis的bos页面上。它还为每个逻辑位流使用两个额外的头页。Ogg Vorbis-bos页面以字节0x01开头,后跟“Vorbis”(标识符共7个字节)。

Ogg知道两种类型的多路复用:并发多路复用(所谓的“分组”(Grouping))和顺序多路复用(称为“链接”(Chaining))。分组(Grouping)定义了如何在同一物理比特流中逐页交错多个逻辑比特流。例如,使用不同逻辑比特流中的不同编解码器来将视频流与几个同步的音轨交织需要分组。另一方面,链接(Chaining)被定义为提供一种简单的机制来连接物理Ogg比特流,这是流应用程序经常需要的。

在分组(Grouping)中,所有逻辑位流的所有bos页必须一起出现在Ogg位流的开头。媒体映射指定初始页面的顺序。例如,特定Ogg视频和Ogg音频比特流的分组(grouping)可以指定物理比特流必须以逻辑视频比特流的bos页开始,然后是音频比特流。与bos页面不同,逻辑位流的eos页面不需要全部连续出现。eos页面可以是“nil”页面,也就是说,不包含任何内容,只包含一个具有位置信息的页头和在页头中设置的eos标志的页面。每个分组的逻辑比特流必须在物理比特流的范围内具有唯一的序列号(unique serial number)。

在链接(Chaining)中,完整的逻辑比特流被连接在一起。比特流不重叠,即给定逻辑比特流的eos页紧接着是下一个逻辑比特流。每个链接的逻辑比特流必须在物理比特流的范围内具有唯一的序列号(unique serial number)。

可以连续地将并行复用的比特流的组串接。当未绑定时,这些组必须作为有效的并发多路复用比特流独立存在。下图显示了这种物理比特流的示意性示例,该物理比特流遵守分组和链式复用比特流的所有规则。

                physical bitstream with pages of
          different logical bitstreams grouped and chained
      -------------------------------------------------------------
      |*A*|*B*|*C*|A|A|C|B|A|B|#A#|C|...|B|C|#B#|#C#|*D*|D|...|#D#|
      -------------------------------------------------------------
       bos bos bos             eos           eos eos bos       eos

在这个例子中,有两个链接的物理比特流,第一个是由三个逻辑比特流A、B和C组成的分组流。第二个物理比特流D链接在分组比特流的末尾之后,分组比特流在其所有分组逻辑比特流的最后一个eos页之后结束。可以看出,分组的比特流从一起开始——所有的bos页面都必须出现在任何数据页面之前。还可以看出,并行复用的比特流的页面不需要符合规则的顺序。可以看出,一个分组的比特流可以在该组中的其他比特流结束之前很久结束。

Ogg不知道关于编解码器数据的任何细节,只是每个逻辑比特流都属于不同的编解码器,来自编解码器的数据按顺序排列,并有位置标记(所谓的“颗粒位置”)。Ogg没有“时间”的概念:它只知道顺序增加的、无单位的位置标记。应用程序只能通过更高层获得时间信息,这些高层可以访问编解码器API来分配和转换颗粒位置或时间。

使用Ogg的媒体映射的特定定义可以对其对Ogg比特流格式的特定使用施加进一步的约束。例如,特定的媒体映射可能要求所有分组比特流的所有eos页面都需要以直接顺序出现。介质映射的一个例子是“Ogg Vorbis”的规范。另一个例子是即将推出的“Ogg Theora”规范,该规范封装了Theora编码的视频数据,通常与包含同步音频和视频的Ogg的Vorbis流多路复用。由于Ogg没有指定封装的并发复用比特流之间的时间关系,因此音频和视频流之间的临时同步将在该媒体映射中指定。为了启用流式传输,来自各种逻辑位流的页面通常将按时间顺序交错。

在这里插入图片描述

🎄五、封装过程

多路复用不同逻辑比特流的过程发生在如上所述的页面级别。然而,编码器提供的比特流作为所谓的“分包”(Packets)移交给Ogg,分包边界(packet boundaries)取决于编码格式。现在将描述将数据包封装到页面中的过程。

从Ogg的角度来看,数据包(packet )可以是任意大小的。特定媒体映射将定义如何对来自特定媒体编码器的数据包进行分组或分解。由于Ogg页面(Ogg pages)的最大大小约为64kBytes,有时一个数据包必须分布在几个页面上。为了简化这个过程,Ogg将每个数据包划分为255字节长的块和最后一个较短的块。这些块被称为“Ogg分段”(Ogg Segments)。它们只是一个逻辑结构,本身没有分段的头部(header)。

一组连续的段(segments )被包装成一个可变长度的页面,页面前面有一个页头部(page)。页面头部(page header)中的分段表(segment table)告诉页面中包含的各个分段(segments)的“Lacing Value”(大小)。页面头部(page header)中的标志告诉一个页是否包含从前一页继续的数据包。注意,lacing value 值位255意味着第二个lacing value 跟随其后在同一数据包中,并且lacing value 值小于255标记在许多附加字节之后的数据包的结束。255个字节(或255个字节的倍数)的数据包以 lacing value 值为 0 终止。还要注意,“nil”(零长度)数据包不是错误;它只包括页头部中的一个值为零的lacing value。

编码针对速度和大多数数据包在50到200字节之间的预期情况进行了优化。这是一个设计理由,而不是一个建议。这种编码既避免了对小分包施加最大分包大小,又避免了对其施加最小开销。相反,例如,简单地在每个数据包的开头使用两个字节,并且具有32kBytes的最大数据包大小,将总是以两倍的分段开销惩罚小数据包(典型情况下<255字节)。使用建议的lacing value,小数据包可以看到最小可能的字节对齐开销(1字节),而大数据包(>512字节)在编码空间上看到相当恒定的~0.5%的开销。

  The following diagram shows a schematic example of a media mapping
   using Ogg and grouped logical bitstreams:

          logical bitstream with packet boundaries
 -----------------------------------------------------------------
 > |       packet_1             | packet_2         | packet_3 |  <
 -----------------------------------------------------------------

                     |segmentation (logically only)
                     v

      packet_1 (5 segments)          packet_2 (4 segs)    p_3 (2 segs)
     ------------------------------ -------------------- ------------
 ..  |seg_1|seg_2|seg_3|seg_4|s_5 | |seg_1|seg_2|seg_3|| |seg_1|s_2 | ..
     ------------------------------ -------------------- ------------

                     | page encapsulation
                     v

 page_1 (packet_1 data)   page_2 (pket_1 data)   page_3 (packet_2 data)
------------------------  ----------------  ------------------------
|H|------------------- |  |H|----------- |  |H|------------------- |
|D||seg_1|seg_2|seg_3| |  |D|seg_4|s_5 | |  |D||seg_1|seg_2|seg_3| | ...
|R|------------------- |  |R|----------- |  |R|------------------- |
------------------------  ----------------  ------------------------

                    |
pages of            |
other    --------|  |
logical         -------
bitstreams      | MUX |
                -------
                   |
                   v

              page_1  page_2          page_3
      ------  ------  -------  -----  -------
 ...  ||   |  ||   |  ||    |  ||  |  ||    |  ...
      ------  ------  -------  -----  -------
              physical Ogg bitstream

在本例中,我们对一个逻辑比特流的封装过程进行了快照。我们可以看到编解码器提供的部分比特流细分为数据包。Ogg封装过程将数据包分割成若干段。本例中的数据包相当大,因此数据包1被分为5个段,其中4个段有255个字节,最后一个较小。数据包2分为4个段,其中3个段有255个字节,最后一个非常小。数据包3分为两个段。然后,封装过程会创建页面,在本例中页面非常小。页面1由数据包1的前三个段组成,页面2包含数据包1中剩余的两个段,页面3包含数据包2的前三页。最后,该逻辑比特流的页面和其他逻辑比特流页面被混合组成一个物理Ogg比特流。

在这里插入图片描述

🎄六、Ogg页面格式

物理Ogg比特流由一系列连接的页面组成。页面大小可变,通常为4-8 kB,最大65307字节。页头包含将逻辑比特流从物理比特流中解复用出来以及执行基本错误恢复和用于查找的地标所需的所有信息。每个页面都是一个自包含的实体,因此页面解码机制可以一次识别、验证和处理单个页面,而不需要整个比特流。

The Ogg page header has the following format:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1| Byte
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| capture_pattern: Magic number for page start "OggS"           | 0-3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| version       | header_type   | granule_position              | 4-7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               | 8-11
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               | bitstream_serial_number       | 12-15
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               | page_sequence_number          | 16-19
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               | CRC_checksum                  | 20-23
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |page_segments  | segment_table | 24-27
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ...                                                           | 28-
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The LSb (least significant bit) comes first in the Bytes.  Fields
with more than one byte length are encoded LSB (least significant
byte) first.

LSb(最低有效位)位于字节中的第一位。长度超过一个字节的字段首先编码LSB(最低有效字节)。

页面头部(page header)中的字段具有以下含义:

1、capture_pattern:表示页面开始的4字节字段。它包含4个字符:OggS。它可以帮助解码器找到页面边界,并在解析损坏的流后重新获得同步。一旦发现捕获模式,解码器就通过计算和比较校验和来验证页面同步和完整性。

2、stream_structure_version:1字节,表示该流中使用的Ogg文件格式的版本号(本文档指定版本0)。

3、header_type_flag:这1字节字段中的位标识该页面的特定类型。

bit 0x01
被设置:页面包含从上一页继续的数据包的数据。
没设置: 页面包含新的数据包 

bit 0x02
被设置:这是逻辑比特流(bos)的第一页 
没设置:此页面不是首页 

bit 0x04
被设置:这是逻辑比特流(eos)的最后一页
没设置:这一页不是最后一页

4、granule_position:包含位置信息的8字节字段。例如,对于音频流,它可能包含在包括此页面上完成的所有帧之后编码的PCM样本的总数。对于视频流,它可能包含在此页面之后编码的视频帧的总数。这是对解码器的提示,并给它一些定时和位置信息。其含义取决于该逻辑比特流的编解码器,并在特定媒体映射中指定。特殊值-1(以2的补码表示)表示此页上没有数据包结束。

5、bitstream_serial_number:包含唯一序列号的4字节字段,通过该唯一序列号来识别逻辑比特流。

6、page_sequence_number:包含页面序列号的4字节字段,使得解码器可以识别页面丢失。该序列号在每个逻辑比特流上分别增加。

7、CRC_checksum:包含页面的32位CRC校验和的4字节字段(包括具有零CRC字段的报头和页面内容)。生成多项式为0x04c11db7。

8、number_page_segments:1字节,给出分段表(segment table.)中编码的分段条目的数量。

9、segment_table:大小为 number_page_segments 个字节。包含此页中所有段的lacing value。每个字节包含一个 lacing value。

以字节为单位的页面头部大小(total header size)由下式给出:

header_size = number_page_segments + 27 [Byte]

以字节为单位的总页面大小由下式给出:页面头部大小 + 所有lacing_values值之和

page_size = header_size + sum(lacing_values: 1..number_page_segments)[Byte]

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考资料:
The Ogg Encapsulation Format Version 0

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

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

相关文章

Vue3入门指南:零基础小白也能轻松理解的学习笔记

文章目录 创建项目开发环境项目目录模板语法属性绑定条件渲染列表渲染事件处理内联事件处理器方法事件处理器&#xff08;常用&#xff09; 事件参数获取 event 事件事件传参 事件修饰符阻止默认事件阻止事件冒泡 数组变化侦测变更方法替换一个数组 计算属性class 绑定单对象绑…

汽车标定技术(一):XCP概述

目录 1.汽车标定概述 2.XCP协议由来及版本介绍 3.XCP技术通览 3.1 XCP上下机通信模型 3.2 XCP指令集 3.2.1 XCP帧结构定义 3.2.2 标准指令集 3.2.3 标定指令集 3.2.4 页切换指令集 3.2.5 数据采集指令集 3.2.6 刷写指令集 3.3 ECU描述文件(A2L)概述 3.3.1 标定上位…

无限上下文,多级内存管理!突破ChatGPT等大语言模型上下文限制

目前&#xff0c;ChatGPT、Llama 2、文心一言等主流大语言模型&#xff0c;因技术架构的问题上下文输入一直受到限制&#xff0c;即便是Claude 最多只支持10万token输入&#xff0c;这对于解读上百页报告、书籍、论文来说非常不方便。 为了解决这一难题&#xff0c;加州伯克利…

物联网AI MicroPython传感器学习 之 QMC5883指南针罗盘传感器

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 一、产品简介 QMC5883是一款表面贴装的集成了信号处理电路的三轴磁性传感器&#xff0c;应用场景主要包括罗盘、导航、无人机、机器人和手持设备等一些高精度的场合。 引脚定义 VCC&#xff1a;3V3&#…

【Java 进阶篇】Java ServletContext详解:获取MIME类型

MIME&#xff08;Multipurpose Internet Mail Extensions&#xff09;类型是一种标识文件类型的文本标签&#xff0c;通常用于指示浏览器如何处理Web服务器返回的文件。在Java Web应用程序中&#xff0c;ServletContext对象提供了一种方便的方法来获取文件的MIME类型。本篇博客…

【实战Flask API项目指南】之五 RESTful API设计

实战Flask API项目指南之 RESTful API设计 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发的世界时…

Redis-命令操作Redis

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.Redis简介 1.1.什么是Redis Redis是一个开源&#xff08;BSD许可&#xff09;&#xff0c;内存存储的数据…

费用预算管理系统

费用预算管理系统 1. 模块概述 《费用管理》以企业费用管理为核心&#xff0c;围绕费用支出审批流程&#xff0c;从费用发生前的事前申请&#xff0c;报销单据审批、付款单据审批&#xff0c;再到出纳付款、会计记账等所有工作流程都在系统中全员、协同完成&#xff1b;并且能…

el-table中的el-input标签修改值,但界面未更新,解决方法

el-table中的el-input标签修改值&#xff0c;界面未更新 在el-table中的el-input里面写的change事件根本不触发&#xff0c;都不打印&#xff0c;试了网络上各种方法都没用 然后换成input事件&#xff0c;input事件会触发&#xff0c;但界面也未更新。我在触发事件的时候&…

微信小程序之开发工具介绍

一、微信小程序开发工具下载 微信小程序开发工具下载可以参考这篇博客《微信小程序开发者工具下载-CSDN博客》 二、开发工具组成部分 如下图所示&#xff0c;开发者工具主要由菜单栏、工具栏、模拟器、编辑器和调试器 5 个部分组成。。 1、菜单栏 菜单栏中主要包括项目、文…

听GPT 讲Rust源代码--library/std(13)

题图来自 Decoding Rust: Everything You Need to Know About the Programming Language[1] File: rust/library/std/src/os/horizon/raw.rs 在Rust源代码中&#xff0c;rust/library/std/src/os/horizon/raw.rs这个文件的作用是为Rust的标准库提供与Horizon操作系统相关的原始…

STM32HAL-完全解耦面向对象思维的架构-时间轮片法使用(timeslice)

目录 概述 一、开发环境 二、STM32CubeMx配置 三、编码 四、运行结果 五、代码解释 六、总结 概述 timeslice是一个时间片轮询框架&#xff0c;完全解耦的时间片轮询框架&#xff0c;非常适合裸机单片机引用。接下来将该框架移植到stm32单片机运行&#xff0c;单片机…

王道计算机网络

一、计算机网络概述 (一)计算机网络基本概念 计算机网络的定义、组成与功能 定义&#xff1a;以能够相互共享资源的方式互连起来的自治计算机系统的集合。 目的&#xff1a;资源共享&#xff0c; 组成单元&#xff1a;自治、互不影响的计算机 网络协议 从不同角度计算机网络…

【Python入门二】安装第三方库(包)

安装第三方库/包 1 使用pip安装2 使用PyCharm软件安装3 离线安装&#xff0c;使用whl文件安装参考 在Python中&#xff0c;有多种安装第三方库的方法&#xff0c;下面是一些常用的方法&#xff1a; 1 使用pip安装 pip是Python中最常用的包管理工具&#xff0c;也是最常用的在线…

PASCAL VOC 格式

文章目录 ImageSets 文件夹Main 文件夹:Segmentation 文件夹:Layout 文件夹:Action 文件夹: Annotations 文件夹主要标签&#xff1a;物体标签&#xff1a; SegmentationClass 文件夹SegmentationObject 文件夹 PASCAL VOC&#xff08;Visual Object Classes&#xff09;是一个…

计算流体动力学(CFD)软件

CFD&#xff0c;英语全称 (Computational Fluid Dynamics&#xff09;&#xff0c;即计算流体动力学。CFD 是近代流体力学&#xff0c;数值数学和计算机科学结合的产物&#xff0c;是一门具有强大生命力的交叉科学。它是将流体力学的控制方程中积分、微分项近似地表示为离散的代…

ardupilot开发 --- 代码解析 篇

0. 前言 根据SITL的断点调试和自己阅读代码的一些理解&#xff0c;写一点自己的注释&#xff0c;有什么不恰当的地方请各位读者不吝赐教。 1. GCS::update_send 线程 主动向MavLink system发送消息包。 1.1 不断向地面站发送飞机状态数据 msg_attitude: msg_location: n…

MYSQL 多表联查详解

目录 一、一个案例引发的多表连接 二、笛卡尔积的错误和与正确的多表查询 2.1、笛卡尔积错误展示 2.2、笛卡尔积解决方法 2.3、练习 三、多表查询分类 3.1、等值连接 vs 非等值连接 3.2、自连接 vs 非自连接 3.3、内连接 vs 外连接 内连接&#xff08;inner join&…

基于FPGA的图像RGB转CMYK实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1、RGB转CMYK的原理 4.2、基于FPGA的实现方法 5.算法完整程序工程 1.算法运行效果图预览 将仿真结果导入到matlab中&#xff0c;得到如下对比结果&#xff1a; 2.算法运行软件版本 matl…

C++虚函数产生的多态

C虚函数产生的多态 1、先看下面代码&#xff0c;参考施雷老师课堂笔记 #include<iostream> #include<vector> #include <algorithm> #include <functional> using namespace std;/* 虚函数&#xff0c;静态绑定和动态绑定覆盖&#xff1a; 基类和派生…