type
status
date
slug
summary
tags
category
icon
password
Property
Mar 11, 2023 08:24 AM

FFmpeg 编程入门

播放器框架

notion image

常见音视频概念

notion image
notion image
notion image

FFmpeg 整体结构

notion image
notion image
notion image

FFmpeg 常用 API 简介

notion image

封装格式相关

notion image
notion image

解码器相关

notion image
  • id 与 name 的区别:不同生产厂家可以有不同的 name,但是相同解码器的 id 要相同。
    • notion image
      notion image
  • 为啥需要 AVCodecContex?
    • notion image
      notion image
notion image

组件注册方式

notion image
  • 以链表形式注册:
    • notion image
 
notion image
notion image

FFmpeg 数据结构

notion image

数据结构之间关系

notion image
notion image
notion image
notion image
notion image

数据结构分析

notion image
notion image
notion image
notion image

FFmpeg 内存模型

notion image
notion image
notion image
notion image
notion image

AVPacket 常用 API

notion image
  • av_packet_free():内部会调用 av_packet_unref() 来减少引用计数。但是,在实际应用中,为了避免内存泄漏,最好调用 av_packet_unref() 来明确地释放已分配的内存。
    • notion image
      notion image
    • 为什么需要临时变量 val ?
      • 使用临时变量 val 的好处在于,它能够保证在释放 arg 中的指针之前,先将指针的值保存到 val 中,确保这个指针指向的内存不会被错误释放,然后再将 arg 中的指针置 NULL,避免出现悬空指针的情况。因此,使用临时变量 val 可以提高程序的稳定性和安全性。
      • 如果先使用 av_free(arg) ,再 memcpy(arg, &(void *){ NULL }, sizeof(arg)); 会不能保证 arg 中的指针被置为 NULL 之前已经被释放了,如果在将 arg 中的指针置为 NULL 之前,还有其他地方引用了这个指针指向的内存,那么这个内存块就会被错误的释放,导致程序出现异常或崩溃。
  • av_packet_unref() av_packet_free() 区别:av_packet_unref()函数用于清空AVPacket结构体中的所有内容,但并不会释放该结构体本身,因此在使用完AVPacket后需要调用该函数进行清空,以免在下一次使用时出现错误。av_packet_free()函数则是用于释放AVPacket结构体本身所占用的内存,包括AVPacket结构体中的数据成员和指向数据缓冲区的指针等,该函数应该在使用完AVPacket并且不再需要该结构体时进行调用。
    • 当你只是暂时不需要使用 AVPacket 数据时,可以使用 av_packet_unref 将其数据置空,而保留其它结构体变量不变,以便复用。
    • 例如,在一个循环中,你多次调用 av_read_frame 读取数据包,每次读取完成后,你需要对这个数据包进行一些处理。如果你不想每次都重新分配一个新的 AVPacket 变量,而是希望重用之前的变量,则可以在每次处理完数据包后调用 av_packet_unref,将其数据部分清空。
      • 当你需要完全释放 AVPacket 变量所占用的空间时,可以使用 av_packet_free 函数。它将释放数据部分和其它结构体变量所占用的内存,并将指向这个变量的指针设置为 NULL。
      • 例如,当你需要手动分配一个 AVPacket 变量时,你可以使用 av_packet_alloc 函数进行分配,完成后需要使用 av_packet_free 函数进行释放。
      • av_init_packet() 【已废弃】:仅仅是把 pkt 的参数设为默认值,要求 pkt 的内存已经分配好了,如果为 NULL,则此处会崩溃
        • notion image
        • av_packet_init() 函数用于初始化一个已经存在的 AVPacket 结构体。这个函数不会分配任何内存,而是将 AVPacket 结构体中的所有字段设置为默认值。这意味着您必须提前分配好 AVPacket 结构体的内存,然后才能使用 av_init_packet() 对其进行初始化。
          • av_packet_alloc() 函数则会自动分配内存并初始化 AVPacket 结构体的所有字段,返回一个指向分配的内存的指针。这个函数可以在创建新的 AVPacket 结构体时非常方便。
          • av_packet_move_ref :用于将对 AVPacket 结构的引用从一个变量移动到另一个变量,而不实际复制数据。这个函数在需要在不同上下文之间传递 AVPacket 时非常有用。例如,如果您有一个生成数据包的解码器和一个消耗它们的过滤器,您可以使用 av_packet_move_ref 将数据包从解码器的上下文移动到过滤器的上下文,而无需复制数据包数据。
            • 该函数有两个参数:目标 AVPacket 指针的指针和源 AVPacket 指针的指针。调用该函数后,目标指针将指向与源指针相同的 AVPacket,并且源指针将被设置为 NULL。
              • av_packet_ref()av_packet_move_ref() 区别:
              • notion image
            • av_packet_clone 是 FFmpeg 库中的一个函数,用于创建一个 AVPacket 的副本,从而可以在不破坏原始数据包的情况下对其进行操作。
              • 该函数会分配新的内存来存储副本的数据,并且会使用与原始数据包相同的数据来填充它。副本的其他字段(如 ptsdtsduration 等)也将设置为与原始数据包相同的值。
              • 需要注意的是,av_packet_clone 分配了一个新的数据包,并复制了原始数据包的内容,因此这可能会消耗大量的内存。

            AVFrame 常用 API

            notion image
             
            《MySQL必知必会》学习笔记奥密克戎应对指南