GStreamer 简明教程(五):Pad 相关概念介绍,Pad Capabilities/Templates

news2024/11/15 21:28:36

系列文章目录

  • GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world!
  • GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline
  • GStreamer 简明教程(三):动态调整 Pipeline
  • GStreamer 简明教程(四):Seek 以及获取文件时长

文章目录

  • 系列文章目录
  • 前言
  • 一、Pad 基本介绍
    • 1.1 Pad
    • 1.2 Pad 类型
      • 1. Sink Pad(接收 Pad)
      • 2. Source Pad(源 Pad)
    • 1.3 Pad 的模式
  • 二、Pad Templates
    • 2.1 Pad Templates的重要性
    • 2.2 Pad Template的组成
    • 2.3 查看Pad Templates
    • 2.4 Pad Templates在协商过程中的作用
  • 三、Pad Capabilities
    • 3.1 组成部分
    • 3.2 定义和使用
    • 3.3 Capabilities示例
    • 3.4 连接协商(Negotiation)
  • 四、Basic tutorial 6: Media formats and Pad Capabilities
    • 4.1 打印 Pad Templates
    • 4.2 打印 Pad Capabilities
    • 4.3 不同状态下 Pad Capabilities 的变化
  • 参考


前言

本章基于官方教程 Basic tutorial 6: Media formats and Pad Capabilities 进行一些说明和补充。本来想对 Basic tutorial 5: GUI toolkit integration 进行讨论的,但我的机器上安装 gtk 后运行程序总是崩溃,因此放弃。

在前面的章节中也有泛泛地提到过 Pad,例如 GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline和 GStreamer 简明教程(三):动态调整 Pipeline。接下来这一章,我们将对 Pad 这个在 GStreamer 中非常重要的概念进行详细阐述。

一、Pad 基本介绍

1.1 Pad

在 GStreamer 中,Pad 是连接不同元素之间的接口,允许它们相互通信和传递数据的概念。每个 GStreamer 元素都包含一个或多个 Pad,其中的数据流通过 Pad 传递。Pad 可以是输入 Pad,用来接收数据,也可以是输出 Pad,用于发送数据。

Pad 有不同的功能,可以用于传输不同类型的数据,如音频、视频或事件等。Pad 之间的连接是通过链接两个元素的 Pad 来实现的,它们会进行数据流的传递和处理。

在 GStreamer 中,Pad 扮演着非常重要的角色,它们定义了元素之间的连接和协作方式,使得不同元素能够协同工作完成复杂的多媒体处理任务。Pad 的概念使得 GStreamer 具有很强的灵活性和可扩展性,能够支持各种不同的数据流处理需求。

1.2 Pad 类型

在这里插入图片描述
在 GStreamer 中,Pad 的基本类型有两种:Sink Pad 和 Source Pad。这两种类型的 Pad 分别对应数据流的输入和输出端点。详细解释如下:

1. Sink Pad(接收 Pad)

  • 作用:用于接收数据。Sink Pad 是元素接收数据的接口。
  • 示例:一个解码器元素的 Sink Pad 会接收编码的音频或视频流。
  • 常见使用场景
    • 解码器接收压缩的媒体流数据。
    • 播放器接收解码后的音视频数据。
    • 多路解复用器接收多个流的数据。

2. Source Pad(源 Pad)

  • 作用:用于输出数据。Source Pad 是元素发送数据的接口。
  • 示例:一个解码器元素的 Source Pad 会输出解码后的音频或视频流。
  • 常见使用场景
    • 文件读取器(如 filesrc)从文件中读取数据并通过 Source Pad 输出。
    • 编码器将原始音视频数据编码后通过 Source Pad 输出。
    • 多路复用器将多个流的数据组合后输出。

1.3 Pad 的模式

  • 固定 Pad(Static Pad):在元素创建时就已经存在,并且它们的生命周期与元素同步。这些 Pad 静态地附着在元素上。
  • 请求 Pad(Request Pad):这些 Pad 是动态创建的,只有在外部请求时才会生成。这种模式特别适用于需要动态添加或删除流的场景,如多路复用器或解复用器元素。

使用 gst-inspect 工具查看元素信息,通过 Pad Templates 中的信息判断 Pad 的模式,例如,以下是一个假设的元素输出的一部分:

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw
    
  SINK template: 'sink_%u'
    Availability: Sometimes
    Capabilities:
      video/x-raw
  • Static Pad:
    例如上面示例中的 SRC template,其 AvailabilityAlways,表示这是一个 Static Pad。

  • Request Pad:
    例如示例中的 SINK template,其 AvailabilitySometimes,表示这是一个 Request Pad(在特定需求时才会生成)。

这是一个具体例子,假设查看 audiotestsrc 元素的信息:

gst-inspect-1.0 audiotestsrc

部分输出可能类似如下:

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw
         format: S16LE
           rate: [ 1, 2147483647 ]
       channels: [ 1, 2147483647 ]
       ...

在这个例子中,src 是一个static pad,因为其 AvailabilityAlways

二、Pad Templates

在GStreamer中,Pad(插口)是元素之间进行数据流动的接口,而Pad Template(插口模板)则是对这些接口进行预定义的蓝图。Pad Templates在GStreamer的流媒体处理中扮演着至关重要的角色,是描述元素间连接能力和数据流类型的基础。它们为元素间进行高效的连接协商和能力匹配提供了基础。

Pad Templates通过定义一个Pad可能具备的所有特性和能力(Capabilities),即其能够处理的数据格式和媒体类型。GStreamer使用Pad Templates在元素连接之前进行参数匹配,从而快速确定是否具备兼容性。

2.1 Pad Templates的重要性

  1. 描述性
    Pad Templates详细描述了Pad可能具备的所有能力,包括数据类型、格式、宽度、高度、采样率等信息。这些描述性信息对于流媒体处理中的连接协商是至关重要的。

  2. 效率提升
    在构建元素时,通过Pad Templates可以尽早判断元素之间的兼容性。若两个元素的Pad Template在能力上没有公共交集,则无需尝试进一步的连接操作。这大大提高了整个管道构建和数据流处理的效率。

  3. 动态Pad创建
    对于像多路复用器或解复用器这样的元素,可能需要根据实际情况动态创建Pad。Pad Templates为这些动态创建的Pad提供了标准,确保新创建的Pad符合预期且具备预定义的能力。

2.2 Pad Template的组成

每个Pad Template由以下部分组成:

  1. Pad名称(Name Template)
    描述Pad的名称模式,支持通配符。例如,sink_%u表示一个动态创建的汇Pad,其名称后缀为数字。

  2. Pad可用性(Pad Availability)

    • GST_PAD_ALWAYS:Pad总是可用的,即Static Pad。
    • GST_PAD_SOMETIMES:Pad按需创建,即Request Pad。
    • GST_PAD_REQUEST:通过显式请求创建的Pad,即Request Pad。
  3. Pad方向(Pad Direction)

    • GST_PAD_SRC:源Pad,用于输出数据。
    • GST_PAD_SINK:汇Pad,用于输入数据。
  4. Capabilities(能力)
    描述Pad能够处理的数据格式和属性。这可能包括诸如媒体类型(音频、视频)、格式(如audio/x-raw)、编码类型(如H.264)、分辨率、帧率、比特率等详细信息。

2.3 查看Pad Templates

通过GStreamer提供的工具gst-inspect-1.0命令,可以查看某个元素的Pad Templates。例如:

gst-inspect-1.0 videotestsrc

示例输出:

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw
         format: RGB
         width: [ 1, 2147483647 ]
         height: [ 1, 2147483647 ]

2.4 Pad Templates在协商过程中的作用

Pad Templates是连接协商过程的第一步。元素在建立连接之前,会通过它们的Pad Templates进行初步匹配。如果两个Pad的模板在定义的能力上存在交集,则进行下一步的协商。实际建立连接后,两个Pad的实际能力可能根据协商结果进一步细化,直到最终确定。

三、Pad Capabilities

在GStreamer中,Pads(插口)是元素间数据流动的接口,而Pad Capabilities(插口能力)是这些接口所能处理的数据类型和属性的详细描述。Pad Capabilities起到定义和描述数据格式的关键作用,为元素间的连接协商奠定基础。

Pad Capabilities是一个结构化的数据描述,它定义了一个Pad能够接受和输出的数据格式、媒体类型及其可能的属性范围。这些能力定义在创建Pad Templates(插口模板)时就已明确,用于元素之间的互操作性和连接匹配。

3.1 组成部分

Pad Capabilities由多个字段组成,主要包括以下内容:

  1. 媒体类型(Media Type)
    描述数据的基本类型,例如音频(audio)、视频(video)、图片(image)等。每种媒体类型还有相应的次级类型,例如audio/x-raw表示原始音频数据。

  2. 格式(Format)
    指定具体的数据格式,例如音频的位深度、编码格式,视频的像素格式等。

  3. 属性(Properties)
    用于进一步细化媒体数据的描述,包括但不限于以下部分:

    • 音频属性
      • 比特率(bitrate)
      • 采样率(sample rate)
      • 声道数(channels)
    • 视频属性
      • 分辨率(resolution):宽度(width)和高度(height)
      • 帧率(framerate)
      • 色彩格式(color format)
  4. 范围和集合(Ranges and Sets)
    Capabilities中的一些属性可以是范围或集合,以表示该能力的变化范围或多个可能的值。例如:

    • 范围(Range):[ 1, 2147483647 ]表示从1到2147483647之间的所有值均有效。
    • 集合(Set):{ I420, NV12, NV21 }表示可以是I420、NV12或NV21中的任意一种。

3.2 定义和使用

Capabilities通常在Pad Template中定义,用来描述一个Pad可能的全部能力。GStreamer使用这些定义在元素连接前进行初步匹配。如果两个Pad的模板在能力上没有公共交集,那么进一步连接会被跳过,从而提高处理效率。

3.3 Capabilities示例

以下是一些Pad Capabilities的示例:

  1. 音频Capabilties:

    audio/x-raw
                format: S16LE
                  rate: [ 1, 2147483647 ]
              channels: [ 1, 2 ]
    
    • 媒体类型audio/x-raw,表示原始音频数据。
    • 格式S16LE,16位有符号小端格式。
    • 采样率rate: [ 1, 2147483647 ],从1到2147483647的范围。
    • 声道数channels: [ 1, 2 ],表示1到2个声道。
  2. 视频Capabilities:

    video/x-raw
                 width: [ 1, 2147483647 ]
                height: [ 1, 2147483647 ]
             framerate: [ 0/1, 2147483647/1 ]
                format: { I420, NV12, NV21, YV12, YUY2, Y42B, Y444, YUV9, YVU9, Y41B, Y800, Y8, GREY, Y16, UYVY, YVYU, IYU1, v308, AYUV, A420 }
    
    • 媒体类型video/x-raw,表示原始视频数据。
    • 分辨率width: [ 1, 2147483647 ]height: [ 1, 2147483647 ],表示支持从1到2147483647范围的宽度和高度。
    • 帧率framerate: [ 0/1, 2147483647/1 ],表示支持从0/1到2147483647/1之间的帧率。
    • 格式format: { I420, NV12, NV21, ... },表示可以是I420、NV12、NV21等多种图像格式。

3.4 连接协商(Negotiation)

在管道构建过程中,Pad Capabilities是连接协商的关键元素。元素通过各自的Pad Template中预定义的Capabilities进行匹配。如果两个元素的Pad在其Capabilities上具有公共交集,则可以建立连接并进一步协商实际的数据传输格式。

协商过程通常包括以下步骤:

  1. 初步匹配(Initial Match)
    元素根据Pad Template的Capabilities进行初步匹配。如果找不到公共交集,则连接失败。

  2. 详细协商(Detailed Negotiation)
    一旦初步匹配成功,元素进一步协商具体的格式、帧率、分辨率等详细参数,直到达成一致或协商失败。

  3. 最终确定(Final Fixation)
    确定最终的传输格式和参数后,Pad的Capabilities被固定,后续数据流按照协商结果进行传输。

四、Basic tutorial 6: Media formats and Pad Capabilities

接下来对 Basic tutorial 6: Media formats and Pad Capabilities 代码部分进行说明,代码太长就不贴了。这部分代码想说明几个内容:

  1. 如何获取元素的 Pad Templates 信息
  2. 如何获取元素的 Pad Capabilities 信息
  3. 不同状态下元素的 Pad Capabilities 的切换

4.1 打印 Pad Templates

static void print_pad_templates_information (GstElementFactory * factory) {
  const GList *pads;
  GstStaticPadTemplate *padtemplate;

  g_print ("Pad Templates for %s:\n", gst_element_factory_get_longname (factory));
  if (!gst_element_factory_get_num_pad_templates (factory)) {
    g_print ("  none\n");
    return;
  }

  pads = gst_element_factory_get_static_pad_templates (factory);
  while (pads) {
    padtemplate = pads->data;
    pads = g_list_next (pads);

    if (padtemplate->direction == GST_PAD_SRC)
      g_print ("  SRC template: '%s'\n", padtemplate->name_template);
    else if (padtemplate->direction == GST_PAD_SINK)
      g_print ("  SINK template: '%s'\n", padtemplate->name_template);
    else
      g_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);

    if (padtemplate->presence == GST_PAD_ALWAYS)
      g_print ("    Availability: Always\n");
    else if (padtemplate->presence == GST_PAD_SOMETIMES)
      g_print ("    Availability: Sometimes\n");
    else if (padtemplate->presence == GST_PAD_REQUEST)
      g_print ("    Availability: On request\n");
    else
      g_print ("    Availability: UNKNOWN!!!\n");

    if (padtemplate->static_caps.string) {
      GstCaps *caps;
      g_print ("    Capabilities:\n");
      caps = gst_static_caps_get (&padtemplate->static_caps);
      print_caps (caps, "      ");
      gst_caps_unref (caps);

    }

    g_print ("\n");
  }
}

这段代码是一个 GStreamer 相关的函数,用于打印一个 GstElementFactory(元素工厂)的 pad 模板信息。以下是代码的详细解释:

  1. 函数接受一个 GstElementFactory 指针作为参数。

  2. 首先打印元素工厂的长名称。

  3. 检查元素是否有 pad 模板,如果没有,打印 “none” 并返回。

  4. 获取元素工厂的静态 pad 模板列表。

  5. 遍历 pad 模板列表,对每个模板执行以下操作:

    • 根据 pad 的方向(SRC、SINK 或未知)打印相应的信息。
    • 打印 pad 的可用性(Always、Sometimes、On request 或未知)。
    • 如果 pad 模板有静态能力(caps),则打印能力信息。
  6. 打印能力信息时,使用 print_caps 函数(未在代码中给出)来格式化输出。

输入如下,整体和 gst-inspect 输出类似

Pad Templates for Audio test source:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw
                 format: { (string)S16LE, (string)S16BE, (string)U16LE, (string)U16BE, (string)S24_32LE, (string)S24_32BE, (string)U24_32LE, (string)U24_32BE, (string)S32LE, (string)S32BE, (string)U32LE, (string)U32BE, (string)S24LE, (string)S24BE, (string)U24LE, (string)U24BE, (string)S20LE, (string)S20BE, (string)U20LE, (string)U20BE, (string)S18LE, (string)S18BE, (string)U18LE, (string)U18BE, (string)F32LE, (string)F32BE, (string)F64LE, (string)F64BE, (string)S8, (string)U8 }
                 layout: { (string)interleaved, (string)non-interleaved }
                   rate: [ 1, 2147483647 ]
               channels: [ 1, 2147483647 ]

Pad Templates for Auto audio sink:
  SINK template: 'sink'
    Availability: Always
    Capabilities:
      ANY

4.2 打印 Pad Capabilities

static void print_pad_capabilities (GstElement *element, gchar *pad_name) {
  GstPad *pad = NULL;
  GstCaps *caps = NULL;

  /* Retrieve pad */
  pad = gst_element_get_static_pad (element, pad_name);
  if (!pad) {
    g_printerr ("Could not retrieve pad '%s'\n", pad_name);
    return;
  }

  /* Retrieve negotiated caps (or acceptable caps if negotiation is not finished yet) */
  caps = gst_pad_get_current_caps (pad);
  if (!caps)
    caps = gst_pad_query_caps (pad, NULL);

  /* Print and free */
  g_print ("Caps for the %s pad:\n", pad_name);
  print_caps (caps, "      ");
  gst_caps_unref (caps);
  gst_object_unref (pad);
}

static gboolean
print_field (GQuark field, const GValue * value, gpointer pfx)
{
  gchar *str = gst_value_serialize (value);

  g_print ("%s  %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);
  g_free (str);
  return TRUE;
}

static void
print_caps (const GstCaps * caps, const gchar * pfx)
{
  guint i;

  g_return_if_fail (caps != NULL);

  if (gst_caps_is_any (caps)) {
    g_print ("%sANY\n", pfx);
    return;
  }
  if (gst_caps_is_empty (caps)) {
    g_print ("%sEMPTY\n", pfx);
    return;
  }

  for (i = 0; i < gst_caps_get_size (caps); i++) {
    GstStructure *structure = gst_caps_get_structure (caps, i);

    g_print ("%s%s\n", pfx, gst_structure_get_name (structure));
    gst_structure_foreach (structure, print_field, (gpointer) pfx);
  }
}

上面三个函数用于打印 GStreamer 元素 pad 的能力(capabilities)信息。让我逐一解释:

  1. print_pad_capabilities 函数:

    • 接受一个 GstElement 和 pad 名称作为参数。
    • 获取指定的 pad。
    • 尝试获取当前协商好的 caps,如果没有,则查询可接受的 caps。
    • 调用 print_caps 函数打印 caps 信息。
    • 最后释放资源。
  2. print_field 函数:

    • 这是一个回调函数,用于打印单个字段的信息。
    • 将字段值序列化为字符串并打印。
    • 返回 TRUE 以继续遍历。
  3. print_caps 函数:

    • 打印 GstCaps 的详细信息。
    • 如果 caps 是 ANY 或 EMPTY,直接打印对应信息。
    • 否则,遍历 caps 中的每个结构(structure)。
    • 对每个结构,打印其名称,然后使用 print_field 函数打印每个字段的详细信息。

这些函数共同工作来提供 GStreamer 元素 pad 的详细能力信息:

  • print_pad_capabilities 获取特定 pad 的 caps。
  • print_caps 负责整体 caps 的打印逻辑。
  • print_field 处理单个字段的打印。

4.3 不同状态下 Pad Capabilities 的变化

示例代码中,分别在不同转态下打印了 autoaudiosink 元素的 pad caps 变换,如下:

In NULL state:
Caps for the sink pad:
      ANY

Pipeline state changed from NULL to READY:
Caps for the sink pad:
      audio/x-raw
                 format: F32LE
                 layout: interleaved
                   rate: 48000
               channels: 2
           channel-mask: 0x0000000000000003
      audio/x-raw
                 format: { (string)F64LE, (string)F64BE, (string)F32LE, (string)F32BE, (string)S32LE, (string)S32BE, (string)U32LE, (string)U32BE, (string)S24_32LE, (string)S24_32BE, (string)U24_32LE, (string)U24_32BE, (string)S24LE, (string)S24BE, (string)U24LE, (string)U24BE, (string)S20LE, (string)S20BE, (string)U20LE, (string)U20BE, (string)S18LE, (string)S18BE, (string)U18LE, (string)U18BE, (string)S16LE, (string)S16BE, (string)U16LE, (string)U16BE, (string)S8, (string)U8 }
                 layout: interleaved
                   rate: [ 1, 2147483647 ]
               channels: 2
           channel-mask: 0x0000000000000003
      audio/x-raw
                 format: { (string)F64LE, (string)F64BE, (string)F32LE, (string)F32BE, (string)S32LE, (string)S32BE, (string)U32LE, (string)U32BE, (string)S24_32LE, (string)S24_32BE, (string)U24_32LE, (string)U24_32BE, (string)S24LE, (string)S24BE, (string)U24LE, (string)U24BE, (string)S20LE, (string)S20BE, (string)U20LE, (string)U20BE, (string)S18LE, (string)S18BE, (string)U18LE, (string)U18BE, (string)S16LE, (string)S16BE, (string)U16LE, (string)U16BE, (string)S8, (string)U8 }
                 layout: interleaved
                   rate: [ 1, 2147483647 ]
               channels: 1

Pipeline state changed from READY to PAUSED:
Caps for the sink pad:
      audio/x-raw
                 format: F32LE
                 layout: interleaved
                   rate: 48000
               channels: 2
           channel-mask: 0x0000000000000003

Pipeline state changed from PAUSED to PLAYING:
Caps for the sink pad:
      audio/x-raw
                 format: F32LE
                 layout: interleaved
                   rate: 48000
               channels: 2
           channel-mask: 0x0000000000000003

这个输出展示了 autoaudiosink 元素在不同状态下 sink pad 的能力(capabilities)变化。让我们逐一解释:

  1. NULL 状态:

    • Caps 显示为 ANY,这意味着在 NULL 状态下,元素还没有进行任何初始化或配置。它可以接受任何类型的音频输入。
  2. READY 状态:

    • 在这个状态下,autoaudiosink 已经初始化,但还没有分配资源或开始处理数据。
    • 显示了三种不同的 caps 配置:
      a. 第一个是一个具体的配置,可能是基于系统默认音频设置。
      b. 第二个和第三个是更广泛的配置,显示了元素可以支持的各种音频格式、采样率和通道数。
    • 这表明 autoaudiosink 在 READY 状态下已经查询了系统音频capabilities,但还没有固定到特定的配置。
  3. PAUSED 状态:

    • Caps 变得更加具体,固定为一种特定的格式(F32LE,48000Hz,2通道)。
    • 这表明在 PAUSED 状态下,autoaudiosink 已经与上游元素协商并选择了一个特定的音频格式。
  4. PLAYING 状态:

    • Caps 保持与 PAUSED 状态相同。
    • 这表明 PLAYING 状态没有引起进一步的 caps 变化,元素已经准备好以协商好的格式处理音频数据。

总结:

  • NULL 到 READY:元素初始化并收集可能的音频配置。
  • READY 到 PAUSED:元素与管道中的其他元素协商,选择特定的音频格式。
  • PAUSED 到 PLAYING:保持协商好的格式,开始处理音频数据。

这个过程展示了 GStreamer 元素如何逐步从一个通用状态转变为特定配置,以适应整个管道的需求。它也说明了为什么在构建 GStreamer 管道时,将元素推进到 PAUSED 状态对于正确配置很重要。

参考

  • Basic tutorial 6: Media formats and Pad Capabilities

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

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

相关文章

自修C++Primer----3.2标准库类型string

目录 1.String的相关操作 1.1拷贝初始化&&直接初始化 1.2显示创建临时对象 1.3读取string对象内容 1.4一次读取多个未知对象 1.5使用getline读取一整行内容 1.6size()的返回值size_type类型 1.7两个string对象比较 1.8string对象赋值 1.9两个string对象相加 1…

策略产品 ①算法逻辑

目录 一、机器学习与AI的关系 二、机器学习全流程 1. 问题定义 2. 数据处理 3. 特征工程 4. 模型训练 5. 模型评估 6. 模型应用 机器学习是AI的关键技术之一&#xff0c;是指机器从历史数据中学习规律&#xff0c;从而提升系统某个性能度量的过程。这篇文章&#xff0c;我们在作…

C Primer Plus第十四章编程练习,仅供参考

第十四章编程练习 第一个问题让我们改写复习题5&#xff0c;创建一个函数去计算一年到某个月份的天数&#xff0c;在一个结构数组中去存储相关数据。完整程序代码以及运行结果如下&#xff1a; #include<stdio.h> #include<string.h> #include<ctype.h> st…

当外接硬盘接入到macOS上,只读不可写时,应当格式化

当windows磁盘格式例如 NTFS 的硬盘接入到macOS上时&#xff0c;会发现无法新建文件夹&#xff0c;无法删除、重命名。原因是磁盘格式对不上macOS&#xff0c;需要进行格式化。格式化时请注意备份重要数据。具体做法如下&#xff0c;在macOS中找到磁盘工具&#xff0c;然后对磁…

【HTML】常用几种模拟动画效果【附源代码】

1. 模拟音频波纹加载效果 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthde…

计算机视觉编程

目录 灰色度 缩略图 拷贝粘贴区域 调整图像尺寸 旋转图像45 画图线、描点 灰色度 灰度是指图像中每个像素的亮度值&#xff0c;用来描述图像中各个像素的明暗程度。在计算机视觉中&#xff0c;灰度可以通过以下方式来计算&#xff1a; 1. 平均值法&#xff1a;将图像中每…

如何在程序中创建出多条线程

多线程是编程中的一个重要概念&#xff0c;它允许程序同时执行多个任务&#xff0c;每个任务可以看作是一个线程。在Java中&#xff0c;多线程尤为常见且强大&#xff0c;它通过允许程序在并发环境下运行&#xff0c;提高了程序的执行效率和响应速度。以下是对Java多线程的详细…

数学建模~~~预测方法--决策树模型

目录 0.直击重点 1.决策树概念 2.节点特征的选择算法 3.基尼系数的计算 4.决策树的分类 5.模型的搭建 6.模型的改进和评价 ROC曲线 参数调优 &#xfeff;GridSearch网格搜索 使用搜索结果重新建模 0.直击重点 这个文章&#xff0c;我们从三个维度进行说明介绍&#…

如何使用Python快速修改文件的标签(如何将歌词嵌入到音乐文件中,含歌词嵌入接口源码)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Python与Music 📒📝 1. 初探音乐文件的标签📝 使用Python修改标签📝 将歌词嵌入音乐文件⚓️ 相关链接 ⚓️📖 介绍 📖 你是否曾经听过一首好听的歌曲,却发现它的标签信息(元数据信息)杂乱无章?甚至找不到歌词?…

【Remi Pi开发板镜像烧录】使用sd卡进行瑞米派镜像的烧录

烧录大典 按照《软件开发指南》4.2.1和4.2.2的顺序进行&#xff0c;具体烧录哪个镜像结合你自己的需求&#xff0c;每个镜像的区别参考以下链接 https://mbb.eet-china.com/forum/topic/143906_1_1.html Tera term界面全屏如下设置看着比较舒服 设置完之后setup->save-&g…

智能优化特征选择|基于鹦鹉优化(2024年新出优化算法)的特征选择(分类器选用的是KNN)研究Matlab程序 【优化算法可以替换成其他优化方法】

智能优化特征选择|基于鹦鹉优化&#xff08;2024年新出优化算法&#xff09;的特征选择&#xff08;分类器选用的是KNN&#xff09;研究Matlab程序 【优化算法可以替换成其他优化方法】 文章目录 一、PO基本原理PO基本原理基本流程示例应用 二、实验结果三、核心代码四、代码获…

npm pack使用

npm pack 的作用主要是从包中创建一个压缩文件&#xff08;tarball&#xff09;&#xff0c;通常具有.tgz扩展名&#xff0c;包含了打包的模块及其依赖&#xff0c;可用于分发或部署。其应用场景包括私有库或组件的分发、离线环境的依赖安装、CI/CD 自动化构建等。 在使用npm管…

UE管理内容 —— FBX Material Pipeline

目录 Material Support Multiple Materials Material Naming Material Ordering Texture Import FBX管道将应用于网格体&#xff08;静态网格体和骨架网格体&#xff09;的材质和纹理&#xff0c;从3D应用程序传输到虚幻&#xff1b; 要转换简单材质&#xff0c;可以导入源…

Gameplay Ability System(通过GameplayEffect里的Execution修改角色属性)

一、关于GameplayEffectExecutionCalculation类 1、查看GameplayEffectExecutionCalculation类的Execute函数 这个函数将编辑器里设置的参数传进来&#xff0c;然后通过计算再返回出去&#xff0c;这个函数被标记为BlueprintNativeEvent&#xff0c;所以我们可以在自己的类Pla…

python怎么去除换行符

在Python的编写过程中&#xff0c;获取到的字符串进场存在不明原因的换行和空格&#xff0c;如何整合成一个单句&#xff0c;成为问题。 方法&#xff1a; 一、去除空格 “ ”代表的为空格 "xyz".strip() # returns "xyz" "xyz".ls…

ES6 class小挑战

// 编码挑战 #2 /* 重新创建挑战 1&#xff0c;但这次使用 ES6 类&#xff1b; a. 添加一个名为 “speedUS ”的获取器&#xff0c;返回当前速度&#xff08;单位&#xff1a;mi/h&#xff09;&#xff08;除以 1.6&#xff09;&#xff1b; 3. a. 添加一个名为 “speedUS ”…

RM遥控键鼠控制总结

硬件&通信介绍 RM比赛中各个参赛队伍使用的都是大疆官方提供的遥控器套装&#xff0c;包括遥控器和接收机&#xff0c;接收机上共三个引脚&#xff1a;VCC&#xff0c;GND&#xff0c;DBUS&#xff08;数据通道&#xff09;&#xff0c;首次使用需要进行遥控器和接收机配对…

Bootstrap 滚动监听(Scrollspy)插件

滚动监听&#xff08;Scrollspy&#xff09;插件&#xff0c;即自动更新导航插件&#xff0c;会根据滚动条的位置自动更新对应的导航目标。其基本的实现是随着您的滚动&#xff0c;基于滚动条的位置向导航栏添加 .active class。 如果您想要单独引用该插件的功能&#xff0c;那…

快团团团长如何高质量选品?如何做最懂顾客的团长!

精准的用户画像&#xff0c;能够帮助团长个性化推荐&#xff0c;精细化营销&#xff0c;提升消费粘性&#xff0c;秒提下单率。 数据中心 用户画像 用户画像的核心&#xff0c;是为用户打标签。 将用户的每个具体信息抽象成标签&#xff0c;利用这些标签将用户具体化&#…

Docker数据卷使用手册

目录 目标 前言 概念 官方文档 匿名卷&#xff08;Anonymous Volumes&#xff09; 简介 案例 命名卷&#xff08;Named Volumes&#xff09; 简介 案例 目标 掌握Volume命令通过演示案例&#xff0c;理解数据卷种类与各自的用途。 前言 我们在很多网上教程上可以看到…