frame.c阅读笔记

本文详细介绍了FFmpeg中的AVFrame结构体,包括av_frame_alloc()、av_frame_free()、av_frame_unref()等函数的用途和工作原理。重点讲解了如何分配和释放音视频数据空间,以及AVFrame中的数据结构和指针管理,特别是av_buffer_unref()在释放内存中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码片段一:

AVFrame *av_frame_alloc(void)
{
    AVFrame *frame = av_mallocz(sizeof(*frame));


    if (!frame)
        return NULL;


    frame->extended_data = NULL;
    get_frame_defaults(frame);


    return frame;
}

说明:

分配AVFrame结构体大小的内存,并将所有字段内容设置为0。

通过get_frame_defaults函数将AVFrame结构体中一些特殊的字段设置为特殊值。

这里并没有分配任何的视频或音频数据空间。


代码片段二:

与av_frame_alloc对应的函数

void av_frame_free(AVFrame **frame)
{
    if (!frame || !*frame)
        return;


    av_frame_unref(*frame);
    av_freep(frame);
}

说明:

av_freep(frame);完成的功能才是真正与av_frame_alloc对应。av_freep(frame)函数完成将av_frame_alloc分配的AVFrame结构体指针内存释放。

av_frame_unref(*frame);函数完成释放音视频数据。


代码片段三:

void av_frame_unref(AVFrame *frame)
{
    int i;


    for (i = 0; i < frame->nb_side_data; i++) {
        av_freep(&frame->side_data[i]->data);
        av_dict_free(&frame->side_data[i]->metadata);
        av_freep(&frame->side_data[i]);
    }
    av_freep(&frame->side_data);


    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
        av_buffer_unref(&frame->buf[i]);
    for (i = 0; i < frame->nb_extended_buf; i++)
        av_buffer_unref(&frame->extended_buf[i]);
    av_freep(&frame->extended_buf);
    av_dict_free(&frame->metadata);
    av_buffer_unref(&frame->qp_table_buf);


    get_frame_defaults(frame);
}

说明:

1、

函数av_buffer_unref(&frame->buf[i]);释放了真正的音视频数据。

依据:get_audio_buffer函数中调用frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;

get_video_buffer函数中调用frame->data[1] = frame->buf[1]->data;   frame->extended_data = frame->data;

从get_audio_buffer及get_video_buffer函数中可以看出extended_data 与data指向同一位置。

2、

当音频通道数超过AV_NUM_DATA_POINTERS(8)时,多余通道数据存放在extended_buf中。


代码片段四:

static int get_video_buffer(AVFrame *frame, int align)
{
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
    int ret, i;


    if (!desc)
        return AVERROR(EINVAL);


    if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
        return ret;


    if (!frame->linesize[0]) {
        for(i=1; i<=align; i+=i) {
            ret = av_image_fill_linesizes(frame->linesize, frame->format,
                                          FFALIGN(frame->width, i));
            if (ret < 0)
                return ret;
            if (!(frame->linesize[0] & (align-1)))
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值