[ffmpeg] AVFrame 功能整理

2023-12-13 10:55:26

背景

AVFrame 主要用来存储编码前的原始数据。

AVFrame 结构体

在 frame.h 文件中

主要变量

uint8_t *data[AV_NUM_DATA_POINTERS]; // 存储每个 planes 的数据
int linesize[AV_NUM_DATA_POINTERS]; // 每一行的音视频数据
uint8_t **extended_data; // 视频,指向 data, 音频有需要则指向新的地址。由于音频可以支持多个声道,比如 22,data 存不在,则需要放到这里。
int width, height; // 视频宽和高
int nb_samples;  // 音频每个通道的采样数
int format; // 音视频格式  AVPixelFormat  AVSampleFormat
int key_frame; // 是不是关键帧
enum AVPictureType pict_type; // 图片类型
AVRational sample_aspect_ratio; // 宽高比
int64_t pts; // 渲染时间
AVRational time_base; // 时间基
int sample_rate; // 采样率
AVBufferRef *buf[AV_NUM_DATA_POINTERS]; // 实际数据存储地方,data 指针指向这里。通过引用来控制是否释放内存。
AVBufferRef **extended_buf; // 类似 buf,存储 extended_data
AVChannelLayout ch_layout; // 音频通道数

AVFrame 函数

常用函数

av_frame_alloc

作用:分配 AVFrame,并设置默认值,通过 av_frame_free 释放。且不会创建 data buffer,因为此时他还不知道要分配多大的内存。

AVFrame *av_frame_alloc(void);
av_frame_free

释放 AVFrame,并减少动态分配变量的引用计数。

void av_frame_free(AVFrame **frame);
av_frame_ref

拷贝 src 的值到 dst,并增加 buf 和 extended_buf 引用 (为啥引用到1 就删除)

int av_frame_ref(AVFrame *dst, const AVFrame *src);
av_frame_unref

减少引用并重置各字段

void av_frame_unref(AVFrame *frame);	
av_frame_get_buffer

为音视频分配内存,调用这个函数前
视频需要设置:格式、宽和高
音频需要设置:采样格式、声道数、每个声道的音频采样数
否则,不知道要分配多大的内存。

int av_frame_get_buffer(AVFrame *frame, int align);
不常用函数
av_frame_clone

相当于 av_frame_alloc()+av_frame_ref()

AVFrame *av_frame_clone(const AVFrame *src);
av_frame_move_ref

将 src 赋值给 dst

void av_frame_move_ref(AVFrame *dst, AVFrame *src);
av_frame_is_writable

判断 frame 是否可写,ffmpeg 好像认为有多个引用,则不可写。应该是需要加锁才能确保安全。

int av_frame_is_writable(AVFrame *frame);
av_frame_make_writable

让 frame 可写,如果有多个引用frame地址,则重新创建一块内存。

int av_frame_make_writable(AVFrame *frame);
av_frame_copy

只拷贝 src 的 buf 到 dst,需要提前确保两者的 buf 内存一样。

int av_frame_copy(AVFrame *dst, const AVFrame *src);
av_frame_copy_props

只拷贝元信息,应该是只那些辅助信息吧,比如 pts、timebase、sidedata等

int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
av_frame_get_plane_buffer

获取某个 plane 的数据

AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane);
side_data

side_data 相关

AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
                                        enum AVFrameSideDataType type,
                                        size_t size);
AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
                                                 enum AVFrameSideDataType type,
                                                 AVBufferRef *buf);

AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
                                        enum AVFrameSideDataType type);
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type);
// 返回 sidedata 类型
const char *av_frame_side_data_name(enum AVFrameSideDataType type);
av_frame_apply_cropping

对数据进行裁剪

int av_frame_apply_cropping(AVFrame *frame, int flags);

文章来源:https://blog.csdn.net/dss875914213/article/details/134841793
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。