【FFmpeg】AVPacket的使用详解

1、AVPacket简介

AVPacket是存储压缩编码数据相关信息的结构体,内部有压缩数据。它通常由解码器导出,或者作为输入传递给解码器,或者传递给muxers。
对于视频,它通常应该包含一个压缩帧。对于音频,它可能包含几个压缩帧。

重要的变量有以下几个:

AVBufferRef *buf;	参考计数
uint8_t *data:		压缩编码后的数据。
	例如对于H.264来说。1个AVPacket的data通常对应一个NAL。
	注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出多媒体文件中的H.264码流
	因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。
int size:			data的大小
int64_t pts:		Presentation timestamp,显示时需要的时间戳
int64_t dts:		Decompression timestamp,解压时间戳
int64_t duration:	此数据包的持续时间
int stream_index:	标识该AVPacket所属的视频/音频流。

2、相关函数

1)av_packet_alloc:分配AVPacket

原型:

AVPacket *av_packet_alloc(void);

注意:
这个函数分配了AVPacket本身,而不是数据缓冲区(uint8_t *data)。使用av_packet_free释放空间。

2)av_new_packet:分配AVPacket->data

原型:

int av_new_packet(AVPacket *pkt, int size);

例如,函数 avcodec_receive_packet 从编码器中获取压缩数据时,会在内部调用av_new_packet 来分配存储压缩数据的空间,使用av_packet_unref释放空间
av_new_packet 内部会调用 atomic_init 来对 AVBufferRef *buf初始化引用计数。

3)av_packet_unref :减少引用计数

原型:

void av_packet_unref(AVPacket *pkt);

对AVPacket缓冲区的引用计数-1(内部调用 atomic_fetch_add_explicit(…, -1, …)),如果引用为个数为1,将释放data缓冲区;
将其余信息包字段重置为它们的默认值。
例如在编码时,循环处理压缩数据,每循环一次都会分配AVPacket->data来存储压缩后的数据(如 avcodec_receive_packet,内部使用 av_new_packet ),处理完压缩数据之后,并且在进入下一次循环之前,记得使用 av_packet_unref 来释放已经分配的AVPacket->data缓冲区。

4)av_packet_free:释放AVPacket

原型:

void av_packet_free(AVPacket **pkt);

av_packet_free首先调用av_packet_unref来减少引用计数,然后释放AVPacket。

5)av_packet_ref:增加引用计数

原型:

int av_packet_ref(AVPacket *dst, const AVPacket *src);

如果src是引用计数的,那么dst和src共用数据,引用计数加1(内部调用 atomic_fetch_add_explicit(…, 1, …));
否则,将给dst分配一个新的缓冲区,并且复制stc的数据;
所有其他字段都是从src复制的;
使用av_packet_unref释放空间。

你可能感兴趣的:(视频)