type
status
date
slug
summary
tags
category
icon
password
Property
Mar 11, 2023 08:24 AM
FFmpeg 编程入门播放器框架常见音视频概念FFmpeg 整体结构FFmpeg 常用 API 简介封装格式相关解码器相关组件注册方式FFmpeg 数据结构数据结构之间关系数据结构分析FFmpeg 内存模型AVPacket 常用 APIAVFrame 常用 API
FFmpeg 编程入门
播放器框架
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F4365e277-3ce7-4f24-bf15-4c7b2a1eabfb%2FUntitled.png?table=block&id=e198b31f-5bce-436c-88a5-2ec32f171eab)
常见音视频概念
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F6b5564a5-be93-4ab5-a701-f6a8b420817e%2FUntitled.png?table=block&id=d8da8dd2-7c81-411d-a2ae-4c6c927fe8a6)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe35b7a87-d2ad-4f68-922f-aca736de1c77%2FUntitled.png?table=block&id=5b0a73b5-aa00-4d03-abf6-3ca18e24ab02)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7f7e5640-bd4e-437f-b557-b4179ee79aac%2FUntitled.png?table=block&id=cad2ff90-03db-4c8c-94b1-d724802e9889)
FFmpeg 整体结构
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F31646a24-b4f5-4014-bf70-30bc07c30545%2FUntitled.png?table=block&id=754b078b-43c3-4608-a137-f8f7e27fd7d8)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fadc6acbe-3c70-4da0-a6a5-c8cb5ba84897%2FUntitled.png?table=block&id=8c5684c1-78e2-46c2-bbe3-2c6e92af70af)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F09c24679-fdd1-4558-8ef9-bbce55967859%2FUntitled.png?table=block&id=a73e23ce-a8e1-4b7d-b899-de9d93a9d618)
FFmpeg 常用 API 简介
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F2d4b6ffa-0faf-4c08-96da-751aabe796a1%2FUntitled.png?table=block&id=5f720421-31b1-4650-90ce-6c37eac35f3c)
封装格式相关
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F038d9357-21ab-4843-97a3-e17ff8dc2663%2FUntitled.png?table=block&id=87ab41b7-9c83-4e05-8850-3bdaa6ce715f)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F74d66265-d2a8-43c9-b632-a84be5cb1fe3%2FUntitled.png?table=block&id=7efdd5f5-6084-45e8-bf79-b6ebb1bb48f5)
解码器相关
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fc7f0c3cc-d4e4-4a9a-b636-5cda2fdc7102%2FUntitled.png?table=block&id=b07ec749-d33e-45b0-9dd4-086fbfeac505)
- id 与 name 的区别:不同生产厂家可以有不同的 name,但是相同解码器的 id 要相同。
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F0d4e15f4-2fe5-4ec1-9539-163806c405fa%2FUntitled.png?table=block&id=05987a58-7bcf-46de-88e3-159617409c9a)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5614dc7b-5cf1-4822-8129-a94cbf5e4f27%2FUntitled.png?table=block&id=e587b486-ac5f-47da-bca1-697203f920a5)
- 为啥需要 AVCodecContex?
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F19dd94e6-b2cb-4563-b5ff-8860dd5d04af%2FUntitled.png?table=block&id=4608984c-d6b6-454e-b2d6-3d2a6c5f906b)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff60edeb1-f473-4ca3-ad0b-10c22348bbeb%2FUntitled.png?table=block&id=df9dc7ac-da48-49e1-98aa-d8e8fc96c5a2)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F51f2845e-5d89-49a8-9353-87806ddc0f22%2FUntitled.png?table=block&id=c0a0aac0-cf7c-44f4-9fc2-1362cb7fb082)
组件注册方式
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F1746ca91-79a0-40e9-b86e-e44e59d320a4%2FUntitled.png?table=block&id=b732f676-8301-466a-bb5f-dad391639bb5)
- 以链表形式注册:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ffab8cdfc-36c0-46c1-a17e-f05743455424%2FUntitled.png?table=block&id=75146684-4919-4b5a-ba44-6efbf40e710c)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F0399741f-34d6-4bbc-ac85-e0500a25a06e%2FUntitled.png?table=block&id=40f042b3-b93b-4f8d-a992-038f51c47dac)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F83e3a7a2-5eb1-4685-8cf2-e1f3086c8318%2FUntitled.png?table=block&id=25a834e4-fdc0-4cb6-9bc1-b7f474e00d36)
FFmpeg 数据结构
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F75f428a8-f463-4b8d-a232-29e922efe3db%2FUntitled.png?table=block&id=f5921856-da12-42e9-b6ba-c754d769c32d)
数据结构之间关系
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F11b094ba-6385-47c2-8f76-316f66804461%2FUntitled.png?table=block&id=7266ec21-d755-4c30-8b1e-a366c0dc5a37)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F2b2e4a23-ba8f-4092-8d88-4069194c66d1%2FUntitled.png?table=block&id=6cacf624-2e91-47c3-857a-02892a255dd7)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fb302c39d-0b64-4c52-a9b7-b5fd98e167f3%2FUntitled.png?table=block&id=1498da05-6965-4369-8145-1130cbec8873)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8d18f5e7-f3fc-4afc-96cc-dd4059af22dd%2FUntitled.png?table=block&id=e46a48d7-e103-4c90-90bf-bdec664a586a)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F0faa3804-e95c-4ccc-841d-dce651cc3f9a%2FUntitled.png?table=block&id=600ded6f-f0d8-4340-9f10-6fb1e911d458)
数据结构分析
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F587c4a4c-f980-4b6a-a902-33fd582573f8%2FUntitled.png?table=block&id=539fa95b-3c4e-4c50-a6c4-d41abf41e8a1)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F360146af-e0f5-4059-bdf0-20ec682ffa34%2FUntitled.png?table=block&id=afd192de-9f74-4ebb-884a-cb82a426e4d1)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F031f7ba3-c4d2-425f-b464-12c04dc9cd33%2FUntitled.png?table=block&id=08e714e3-b58d-47e9-88cf-eb69dc6c7b24)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F3fb773df-440f-41a4-9b27-758aa9665723%2FUntitled.png?table=block&id=bd4ee3da-93ae-4c16-bbdc-823fa4a34833)
FFmpeg 内存模型
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F6b0c10f9-f673-4b61-886c-321796080286%2FUntitled.png?table=block&id=90c2f651-a39a-4572-b0b0-ac0dfea5867c)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F08c43382-7d82-4278-acbf-bc75ad531e7b%2FUntitled.png?table=block&id=be20a095-b993-438f-ac89-60556db68cf1)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F412063db-ea1c-49fc-8772-a4338a24549e%2FUntitled.png?table=block&id=23364e98-d8d6-41bd-9a96-dabb9fc5b4c8)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F60e9adae-9cf4-46b9-92ca-8d97d47b1e65%2FUntitled.png?table=block&id=3c6194d2-a012-4131-9229-a2035dbbfbfb)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ffd2f7536-d580-41b7-aa8a-87f7f827c36e%2FUntitled.png?table=block&id=d89f7898-ee9c-4be9-92d9-fad6f5bd1d67)
AVPacket 常用 API
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F1fce70e8-1671-40b8-8648-f394f4d84aa5%2FUntitled.png?table=block&id=ec447d4a-c9fa-4cd3-902b-ec7f1f307f01)
av_packet_free()
:内部会调用av_packet_unref()
来减少引用计数。但是,在实际应用中,为了避免内存泄漏,最好调用av_packet_unref()
来明确地释放已分配的内存。- 为什么需要临时变量
val
? - 使用临时变量
val
的好处在于,它能够保证在释放arg
中的指针之前,先将指针的值保存到val
中,确保这个指针指向的内存不会被错误释放,然后再将arg
中的指针置NULL
,避免出现悬空指针的情况。因此,使用临时变量val
可以提高程序的稳定性和安全性。 - 如果先使用
av_free(arg)
,再memcpy(arg, &(void *){ NULL }, sizeof(arg));
会不能保证arg
中的指针被置为NULL
之前已经被释放了,如果在将arg
中的指针置为NULL
之前,还有其他地方引用了这个指针指向的内存,那么这个内存块就会被错误的释放,导致程序出现异常或崩溃。
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fe6b06da9-c164-4118-9c0e-3122166cfe36%2FUntitled.png?table=block&id=b4616e48-ab02-4ac6-8a40-bc07d531dc6d)
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F955e3836-aca2-4c86-a120-27839d2a453c%2FUntitled.png?table=block&id=f7322d3f-aba6-42a2-9679-bd3b0f672901)
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,则此处会崩溃av_packet_init()
函数用于初始化一个已经存在的AVPacket
结构体。这个函数不会分配任何内存,而是将AVPacket
结构体中的所有字段设置为默认值。这意味着您必须提前分配好AVPacket
结构体的内存,然后才能使用av_init_packet()
对其进行初始化。av_packet_alloc()
函数则会自动分配内存并初始化AVPacket
结构体的所有字段,返回一个指向分配的内存的指针。这个函数可以在创建新的AVPacket
结构体时非常方便。
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F3a91f8e7-2643-4c3a-a562-a63d7c5d0e69%2FUntitled.png?table=block&id=f97f921b-4779-4199-9c6b-27baa49215da)
av_packet_move_ref
:用于将对 AVPacket 结构的引用从一个变量移动到另一个变量,而不实际复制数据。这个函数在需要在不同上下文之间传递 AVPacket 时非常有用。例如,如果您有一个生成数据包的解码器和一个消耗它们的过滤器,您可以使用av_packet_move_ref
将数据包从解码器的上下文移动到过滤器的上下文,而无需复制数据包数据。- 该函数有两个参数:目标 AVPacket 指针的指针和源 AVPacket 指针的指针。调用该函数后,目标指针将指向与源指针相同的 AVPacket,并且源指针将被设置为 NULL。
av_packet_ref()
与av_packet_move_ref()
区别:
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fde82f1ff-5f65-4bfd-812f-ab814d59234a%2FUntitled.png?table=block&id=f608652e-43bc-4bf6-b991-8d08b6cc79c2)
av_packet_clone
是 FFmpeg 库中的一个函数,用于创建一个 AVPacket 的副本,从而可以在不破坏原始数据包的情况下对其进行操作。- 该函数会分配新的内存来存储副本的数据,并且会使用与原始数据包相同的数据来填充它。副本的其他字段(如
pts
、dts
、duration
等)也将设置为与原始数据包相同的值。 - 需要注意的是,
av_packet_clone
分配了一个新的数据包,并复制了原始数据包的内容,因此这可能会消耗大量的内存。
AVFrame 常用 API
![notion image](https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fd739d1b0-974a-421a-a5b3-a236bc2fc071%2FUntitled.png?table=block&id=dff88501-5479-4678-8882-c06350b94614)
- 作者:OctalZero
- 链接:https://octalzero.com/article/acc8c48f-fef9-40b2-b9bf-41754bbd059e
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章