说明几点:
1. AVPacket中的buf, 是AVBufferBuf结构体,这个结构体是个单链表, 只有data和size两个元素, 分别指向的是AVPacket中的data和size
void av_init_packet(AVPacket *pkt)
{
pkt->pts = AV_NOPTS_VALUE;
pkt->dts = AV_NOPTS_VALUE;
pkt->pos = -1;
pkt->duration = 0;
pkt->convergence_duration = 0;
pkt->flags = 0;
pkt->stream_index = 0;
#if FF_API_DESTRUCT_PACKET
pkt->destruct = NULL;
#endif
pkt->buf = NULL; // 数据域没有, 为空
pkt->side_data = NULL;
pkt->side_data_elems = 0;
}
int av_new_packet(AVPacket *pkt, int size)
{
AVBufferRef *buf = NULL;
//判断size是否正确
if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
//分配size大小
av_buffer_realloc(&buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!buf)
return AVERROR(ENOMEM);
memset(buf->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
av_init_packet(pkt);
pkt->buf = buf;
pkt->data = buf->data; //data域大小
pkt->size = size;
#if FF_API_DESTRUCT_PACKET
pkt->destruct = dummy_destruct_packet;
#endif
return 0;
}
/* Makes duplicates of data, side_data, but does not copy any other fields */
//只复制数据域
static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup)
{
pkt->data = NULL;
pkt->side_data = NULL;
if (pkt->buf) {
AVBufferRef *ref = av_buffer_ref(src->buf);
if (!ref)
return AVERROR(ENOMEM);
pkt->buf = ref;
pkt->data = ref->data;
} else {
DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
}
#if FF_API_DESTRUCT_PACKET
pkt->destruct = dummy_destruct_packet;
#endif
if (pkt->side_data_elems && dup)
pkt->side_data = src->side_data;
if (pkt->side_data_elems && !dup) {
return av_copy_packet_side_data(pkt, src);
}
return 0;
failed_alloc:
av_destruct_packet(pkt);
return AVERROR(ENOMEM);
}
int av_copy_packet_side_data(AVPacket *pkt, AVPacket *src);
源代码中还有一系列不常用的packet操作