【FFMPEG】AVFrame中buffer分配的两种方式

AVFrame在使用ffmpeg进行编解码过程中,是最基本的数据结构。

在某些场景下,需要对AVFrame的数据区域进行提前分配,有两种方法,需要根据自己的需求来使用。

(1)

 * This function will fill AVFrame.data and AVFrame.buf arrays and, if
 * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.

 * For planar formats, one buffer will be allocated for each plane.

int av_frame_get_buffer(AVFrame *frame, int align);

使用该接口分配到的数据空间,是可复用的,即内部有引用计数(reference),本次对frame data使用完成,可以解除引用,av_frame_unref(AVFrame *frame),调用后,引用计数减1,如果引用计数变为0,则释放data空间。

当然,也可以添加引用,接口:av_frame_ref(AVFrame *dst, const AVFrame *src)。

(2)

 * Allocate an image with size w and h and pixel format pix_fmt, and
 * fill pointers and linesizes accordingly.
 * The allocated image buffer has to be freed by using
 * av_freep(&pointers[0]).

int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);

如上接口,和(1)不同在于,(1)只要输入frame指针即可,而本接口看不到frame的数据结构,相比(1),分配的级别更低,看注释中“The allocated image buffer has to be freed by using  av_freep(&pointers[0])”,即,这种分配方式,不能用(2)中的解除引用来进行隐形释放了,需要自行调用释放才行。

注意使用过程中的坑:使用(1)进行分配后,调用ffmpeg某底层接口,结果,该接口对输入的frame做了一次解除引用,而外部调用并不知晓本次操作,从而导致可能的内存误释放,进而引起程序崩溃。

两个接口使用的代码示例:

AVFrame *AllocFrame(enum AVPixelFormat format, int width, int height)
{
	AVFrame *frame = av_frame_alloc();
	if (!frame) return NULL;
	frame->format = format;
	frame->width = width;
	frame->height = height;
	frame->pts = 0;

	int ret = av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, (enum AVPixelFormat)frame->format, 1);

	if (ret < 0)
	{
		av_frame_free(&frame);
		return NULL;
	}
	return frame;
}
AVFrame *AllocFrame(enum AVPixelFormat pix_fmt, int width, int height) {
  AVFrame *frame;
  int ret;
  frame = av_frame_alloc();
  if (!frame) return NULL;
  frame->format = pix_fmt;
  frame->width = width;
  frame->height = height;
  ret = av_frame_get_buffer(frame, 32);
  if (ret < 0) {    
  av_frame_free(&frame);   
  return NULL;
  }
  return frame;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
AVFrameFFmpeg的一个结构体,用于表示视频帧的数据。它包含了视频帧的像素数据、宽度、高度、格式等信息。在使用AVFrame之前,需要先分配内存,并设置其各个字段的值。可以使用av_frame_alloc()函数来分配AVFrame实例,并使用av_frame_get_buffer()或av_image_alloc()函数来分配像素数据的内存。其av_frame_get_buffer()函数会自动选择最优的对齐方式分配内存,而av_image_alloc()函数可以指定像素数据的对齐方式。通过设置AVFrame的width、height和format字段,可以指定视频帧的宽度、高度和像素格式。总之,AVFrame是用于存储和处理视频帧数据的关键结构体。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [FFmpeg数据结构AVFrame](https://blog.csdn.net/irainsa/article/details/128977176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [FFMPEG关键结构体——AVFrame](https://blog.csdn.net/PPPPPPPKD/article/details/125586279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值