现在的位置: 首页 > 综合 > 正文

ffmpeg之AVPacket笔记

2019年03月08日 ⁄ 综合 ⁄ 共 1493字 ⁄ 字号 评论关闭

每一个包是一个完整的数据帧,来暂存解复用之后、解码之前的媒体数据(一个音/视频帧、一个字幕包等)及附加信息(解码时间戳、显示时间戳、时长等)

//注意保存音视频数据包的内存

是 malloc 出来的,用完后应及时用 free 归还给系统

typedef struct AVPacket
{
    int64_t pts;
    int64_t dts;
    int64_t pos;
    uint8_t *data;//数据首地址
    int size;
    int stream_index;
    int flags;//flags为标志域,1表示该数据是一个关键帧
    void(*destruct)(struct AVPacket*);//释放数据缓冲区的函数指针
} AVPacket;

AVPacket本身只是个容器,它data成员引用实际的数据缓冲区。这个缓冲区通常是由av_new_packet创建的,但也可能由 FFMPEG的API创建(如av_read_frame)。当某个AVPacket结构的数据缓冲区不再被使用时,要需要通过调用 av_free_packet释放

而av_new_packet实现如下:(也有 av_init_packet)

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;
}

av_free_packet实现:

 static inline void av_free_packet(AVPacket *pkt)
 {
if (pkt && pkt->destruct)
pkt->destruct(pkt);
}

AVPacketList 仅含有一个 AVPacket,和传统的很多很多节点的 list

不同,不要被 list 名字迷惑。

typedef struct AVPacketList
{
AVPacket pkt;
struct AVPacketList *next; // 用于把各个 AVPacketList 串联起来。
} AVPacketList;

抱歉!评论已关闭.