FFMPEG 之 AVPacket

本文详细介绍了FFmpeg中的AVPacket、AVBufferRef和AVBuffer之间的关系,包括数据操作、引用计数管理、内存分配与释放等,重点展示了如何使用这些数据结构进行流媒体数据处理。

前言:

    本文介绍FFMPEG的AVPacket相关内容:

  1. AVPacket在FFMPEG中用来保存Demux分离出来的压缩的ES流信息。

  2. AVBufferRef表示AVBuffer的引用,和AVBuffer的关系是多个AVBufferRef对一个AVBuffer。

  3. AVBuffer 实现引用计数,其参数refcount表示正在使用这个AVBuffer的AVBufferRef个数。

使用AVPacket时,通过调用av_buffer_alloc获得表示AVBufferRef的buf和AVBuffer,数据操作可在获得buf后读写pkt->data结构体实现,本文FFMPEG使用版本ffmpeg-4.2.2。

AVPacket,AVBufferRef,AVBuffer关系总结

关系图

引用层次关系可以简述为:AVPacket ->AVBufferRef->AVBuffer->refcount

总结

API解读

AVPacket *av_packet_alloc(void)
{
    AVPacket *pkt = av_mallocz(sizeof(AVPacket));
    if (!pkt)
        return pkt;
    /* 
     *1. 释放side_data,side_data类似extradata,比如保存ADTS的采样率,声道等信息。
         在FFMPEG中用AVPacketSideDataType这个枚举类型来描述,Android的MetaData就是一种side_data。
         封装在MP4,FLV,MKV中的H264,H265的SPS,PPS信息也存在于extradata中,push给解码器的时候,需要事先把这些Header加上。
         此处av_freep(&pkt->side_data)时,用free或者_aligned_free函数释放了0地址。
          GCC手册中描述,free的参数可以是0,也就是说free 0地址多次是可以的,什么动作也不会发生。但如果free的参数非calloc,malloc,realloc,则结果未定义。
    *2. 如果AVBufferRef存在,则消灭他。
    *3. 给AVPacket的成员赋初值
    */
    av_packet_unref(pkt);

    return pkt;
}

/* 带了size参数意味着可以生成AVBufferRef和AVBuffer */
int av_new_packet(AVPacket *pkt, int size)
{
    AVBufferRef *buf = NULL;
    /* 
    * 1. AVBufferRef为空时,流程同av_buffer_alloc,先创建data空间,再创建AVBuffer,最后创建AVBufferRef并返回。此时设置BUFFER_FLAG_REALLOCATABLE标记。
    * 2. AVBufferRef不空时,调用av_buffer_realloc:
        a.AVBuffer的flag不带有BUFFER_FLAG_REALLOCATABLE标记,或不能写(READONLY或者引用计数不是1),或者data指向与AVBufferRef不一致,则重新分配AVBufferRef并释放之前的AVBufferRef。
        b.否则不用重新分配AVBufferRef,直接av_realloc(buf->buffer->data, size)。
    */
    int ret = packet_alloc(&buf, size);
    if (ret < 0)
        return ret;

    av_init_packet(pkt);
    pkt->buf      = buf;
    pkt->data     = buf->data;
    pkt->size     = size;

    return 0;
}

/* 两个packet共享AVBuffer,但side data不共享 */
int av_packet_ref(AVPacket *dst, const AVPacket *src)
{
    int ret;
    /* 复制src的内容到dst,整这一出是为了深拷贝。
    * 把src中side data全部拷贝到dst中去,而不是仅仅传个指针到dst。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值