AVPacket数据模型与API
内存模型
每一个AVPacket内含一个AVBufferRef的引用,指向真正的数据存储区域AVBuffer:
struct AVBufferRef { AVBuffer* buf; }
struct AVBuffer { uint8_t *data; int size; atomic_uint refcount; }
|
常用API
函数原型 |
说明 |
AVPacket *av_packet_alloc(void); |
分配 AVPacket 结构体。此时与数据缓冲区无关。 |
void av_packet_free(AVPacket **pkt); |
释放 AVPacket 。与 av_packet_alloc 对应。 |
void av_init_packet(AVPacket *pkt); |
初始化 AVPacket 。只是单纯初始化 pkt 字段。 |
int av_new_packet(AVPacket *pkt, int size); |
给 AVPacket 的 buf 分配内存,引用计数初始化为 1。av_init + set buf |
int av_packet_ref(AVPacket *dst, const AVPacket *src); |
增加引用计数。 |
void av_packet_unref(AVPacket *pkt); |
减少引用计数。 |
void av_packet_move_ref(AVPacket *dst, AVPacket *src); |
转移引用计数。dst 指向了src 数据,src 重置。 |
AVPacket *av_packet_clone(const AVPacket *src); |
等同于 av_packet_alloc() + av_packet_ref() 的操作。 |
example
av_packet_alloc和av_packet_free
AVPacket *pkt = NULL; pkt = av_packet_alloc(); int ret = av_new_packet(pkg, 1024);
av_packet_free(&pkt);
|
av_init_packet
用于初始化pkt,但是可以被av_new_packet省略。
AVPacket *pkt = NULL; pkt = av_packet_alloc();
av_init_packet(pkt); int ret = av_new_packet(pkg, 1024); av_packet_free(&pkt);
|
另一种用法是直接用=
复制pkt结构体时,由于没有增加引用,因此多了一个pkt,需要用init来干掉。实现类似move_ref的效果。
AVPacket *pkt1 = NULL; AVPacket *pkt2 = NULL; pkt1 = av_packet_alloc(); pkt2 = av_packet_alloc();
int ret = av_new_packet(pkt1, 1024);
*pkt2 = *pkt1; av_init_packet(pkt1);
av_packet_free(&pkt1); av_packet_free(&pkt2);
|
warning
不要在已经有buf的AVPacket调用av_init_packet!其会置空内部buf,但不会释放buf。
AVPacket *pkt = NULL; pkt = av_packet_alloc(); int ret = av_new_packet(pkg, 1024);
av_init_packet(pkt); av_packet_free(&pkt);
|
av_packet_move_ref
AVPacket *pkt1 = NULL; AVPacket *pkt2 = NULL; pkt1 = av_packet_alloc(); pkt2 = av_packet_alloc();
int ret = av_new_packet(pkt1, 1024); av_packet_move_ref(pkt2, pkt1);
av_packet_free(&pkt1); av_packet_free(&pkt2);
|
av_packet_clone
AVPacket *pkt1 = NULL; AVPacket *pkt2 = NULL; pkt1 = av_packet_alloc();
int ret = av_new_packet(pkt1, 1024); pkt2 = av_packet_clone(pkt1);
av_packet_free(&pkt1); av_packet_free(&pkt2);
|
av_packet_ref和av_packet_unref
AVPacket *pkt1 = NULL; AVPacket *pkt2 = NULL; pkt1 = av_packet_alloc();
int ret = av_new_packet(pkt1, 1024); av_packet_ref(pkt2, pkt1);
av_packet_unref(pkt1); av_packet_unref(pkt1);
av_packet_unref(pkt2);
av_packet_free(&pkt1); av_packet_free(&pkt2);
|