FFMpeg AVFrame 的概念.
拿这个简单的例子测试一下吧。
$ cat avframe.c
#include "libavcodec/avcodec.h"
// 测试 frame 概念, 查找内存泄漏
void av_frame_test()
{
AVFrame *frame = NULL;
int ret = 0;
frame = av_frame_alloc();
// 1024 *2 * (16/8) =
frame->nb_samples = 1024;
frame->format = AV_SAMPLE_FMT_S16;//AV_SAMPLE_FMT_S16P AV_SAMPLE_FMT_S16
frame->channel_layout = AV_CH_LAYOUT_MONO; //AV_CH_LAYOUT_MONO AV_CH_LAYOUT_STEREO
ret = av_frame_get_buffer(frame, 0); // 根据格式分配内存
if(frame->buf && frame->buf[0])
printf("%s(%d) 1 frame->buf[0]->size = %d\n", __FUNCTION__, __LINE__, frame->buf[0]->size); //受frame->format等参数影响
if(frame->buf && frame->buf[1])
printf("%s(%d) 1 frame->buf[1]->size = %d\n", __FUNCTION__, __LINE__, frame->buf[1]->size); //受frame->format等参数影响
if(frame->buf && frame->buf[0]) // 打印referenc-counted,必须保证传入的是有效指针
printf("%s(%d) ref_count1(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));
ret = av_frame_make_writable(frame); // 当frame本身为空时不能make writable
printf("av_frame_make_writable ret = %d\n", ret);
if(frame->buf && frame->buf[0]) // 打印referenc-counted,必须保证传入的是有效指针
printf("%s(%d) ref_count2(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));
av_frame_unref(frame); // 释放frame, 当bufs refcount 为0时, 会执行buf释放器,释放buf
if(frame->buf && frame->buf[0]) // 已释放,frame->buf 为0, 不会打印该行了
printf("%s(%d) ref_count3(frame) = %d\n", __FUNCTION__, __LINE__, av_buffer_get_ref_count(frame->buf[0]));
av_frame_free(&frame);
}
hjj@hjj-OP7090:/$ cat main.c
#include <stdio.h>
void av_frame_test();
int main()
{
av_frame_test();
printf("finished!\n");
return 0;
}
可以查一下AVFrame 在哪里释放内存的,实际上是在这里。
(gdb) bt
#0 av_free (ptr=0x5555555595c0) at libavutil/mem.c:224
#1 0x00007ffff7cea5b5 in av_buffer_default_free (opaque=0x0, data=0x5555555595c0 "") at libavutil/buffer.c:64
#2 0x00007ffff7cea7b1 in buffer_replace (dst=0x555555559460, src=0x0) at libavutil/buffer.c:120
#3 0x00007ffff7cea808 in av_buffer_unref (buf=0x555555559460) at libavutil/buffer.c:130
#4 0x00007ffff7cfadc9 in av_frame_unref (frame=0x555555559340) at libavutil/frame.c:563
#5 0x0000555555555420 in av_frame_test () at avframe.c:29
#6 0x00005555555554a6 in main () at main.c:5